@fluidframework/container-loader 2.0.0-internal.5.2.0 → 2.0.0-internal.5.3.1
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/CHANGELOG.md +11 -0
- package/dist/connectionManager.d.ts +1 -1
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/connectionManager.js.map +1 -1
- package/dist/connectionStateHandler.d.ts +1 -1
- package/dist/connectionStateHandler.d.ts.map +1 -1
- package/dist/connectionStateHandler.js.map +1 -1
- package/dist/container.d.ts +10 -4
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +22 -9
- package/dist/container.js.map +1 -1
- package/dist/containerContext.d.ts +5 -12
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/containerContext.js +4 -16
- package/dist/containerContext.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +38 -6
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/contracts.d.ts +1 -3
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/deltaManager.d.ts +2 -1
- package/dist/deltaManager.d.ts.map +1 -1
- package/dist/deltaManager.js.map +1 -1
- package/dist/disposal.d.ts +13 -0
- package/dist/disposal.d.ts.map +1 -0
- package/dist/disposal.js +25 -0
- package/dist/disposal.js.map +1 -0
- package/dist/loader.d.ts +1 -2
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.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/dist/protocol.d.ts +6 -0
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +17 -1
- package/dist/protocol.js.map +1 -1
- package/dist/quorum.d.ts +1 -17
- package/dist/quorum.d.ts.map +1 -1
- package/dist/quorum.js +1 -17
- package/dist/quorum.js.map +1 -1
- package/lib/connectionManager.d.ts +1 -1
- package/lib/connectionManager.d.ts.map +1 -1
- package/lib/connectionManager.js.map +1 -1
- package/lib/connectionStateHandler.d.ts +1 -1
- package/lib/connectionStateHandler.d.ts.map +1 -1
- package/lib/connectionStateHandler.js.map +1 -1
- package/lib/container.d.ts +10 -4
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +24 -11
- package/lib/container.js.map +1 -1
- package/lib/containerContext.d.ts +5 -12
- package/lib/containerContext.d.ts.map +1 -1
- package/lib/containerContext.js +4 -16
- package/lib/containerContext.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +38 -6
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/contracts.d.ts +1 -3
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/deltaManager.d.ts +2 -1
- package/lib/deltaManager.d.ts.map +1 -1
- package/lib/deltaManager.js.map +1 -1
- package/lib/disposal.d.ts +13 -0
- package/lib/disposal.d.ts.map +1 -0
- package/lib/disposal.js +21 -0
- package/lib/disposal.js.map +1 -0
- package/lib/loader.d.ts +1 -2
- package/lib/loader.d.ts.map +1 -1
- package/lib/loader.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/lib/protocol.d.ts +6 -0
- package/lib/protocol.d.ts.map +1 -1
- package/lib/protocol.js +15 -0
- package/lib/protocol.js.map +1 -1
- package/lib/quorum.d.ts +1 -17
- package/lib/quorum.d.ts.map +1 -1
- package/lib/quorum.js +1 -16
- package/lib/quorum.js.map +1 -1
- package/package.json +18 -14
- package/src/connectionManager.ts +1 -2
- package/src/connectionStateHandler.ts +1 -1
- package/src/container.ts +49 -25
- package/src/containerContext.ts +2 -18
- package/src/containerStorageAdapter.ts +46 -4
- package/src/contracts.ts +1 -3
- package/src/deltaManager.ts +15 -8
- package/src/disposal.ts +25 -0
- package/src/loader.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/protocol.ts +18 -0
- package/src/quorum.ts +2 -31
- package/dist/deltaManagerProxy.d.ts +0 -42
- package/dist/deltaManagerProxy.d.ts.map +0 -1
- package/dist/deltaManagerProxy.js +0 -79
- package/dist/deltaManagerProxy.js.map +0 -1
- package/lib/deltaManagerProxy.d.ts +0 -42
- package/lib/deltaManagerProxy.d.ts.map +0 -1
- package/lib/deltaManagerProxy.js +0 -74
- package/lib/deltaManagerProxy.js.map +0 -1
- package/src/deltaManagerProxy.ts +0 -109
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,EAGN,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;AAOvC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAU,CAAC;AAE7C,mDAAmD;AACnD,MAAM,CAAN,IAAY,UAIX;AAJD,WAAY,UAAU;IACrB,iCAAmB,CAAA;IACnB,mCAAqB,CAAA;IACrB,6BAAe,CAAA;AAChB,CAAC,EAJW,UAAU,KAAV,UAAU,QAIrB;AAgBD,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IACrD,YACC,UAA+B,EAC/B,cAA+B,EAC/B,YAAiD,EACxC,QAAwB;QAEjC,KAAK,CACJ,UAAU,CAAC,qBAAqB,EAChC,UAAU,CAAC,cAAc,EACzB,kBAAkB,EAClB,cAAc,CAAC,OAAO,EACtB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,MAAM,EACrB,YAAY,CACZ,CAAC;QAVO,aAAQ,GAAR,QAAQ,CAAgB;QAYjC,oFAAoF;QACpF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CACjD,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAC5C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;YAC3D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;SAClD;IACF,CAAC;IAEM,aAAa,CAAC,OAAuB;;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAyC,CAAC;QACvE,QAAQ,YAAY,CAAC,IAAI,EAAE;YAC1B,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC3C,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE;oBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;wBAC3B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;qBACrC;iBACD;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC;gBAC3B,MAAM,SAAS,GAAG,YAAY,CAAC,OAAwB,CAAC;gBACxD,2DAA2D;gBAC3D,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;oBACrC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;iBAC9D;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC5B,MAAM,YAAY,GAAG,YAAY,CAAC,OAAiB,CAAC;gBACpD,2DAA2D;gBAC3D,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,0CAAE,IAAI,MAAK,MAAM,EAAE;oBAC3D,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;iBACzC;gBACD,MAAM;aACN;YACD;gBACC,MAAM;SACP;IACF,CAAC;CACD","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\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tISignalClient,\n\tISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\treadonly audience: IAudienceOwner,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tOnlyValidTermValue,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAGN,iBAAiB,GACjB,MAAM,+BAA+B,CAAC;AAOvC,8FAA8F;AAC9F,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAU,CAAC;AAE7C,mDAAmD;AACnD,MAAM,CAAN,IAAY,UAIX;AAJD,WAAY,UAAU;IACrB,iCAAmB,CAAA;IACnB,mCAAqB,CAAA;IACrB,6BAAe,CAAA;AAChB,CAAC,EAJW,UAAU,KAAV,UAAU,QAIrB;AAgBD,MAAM,OAAO,eAAgB,SAAQ,iBAAiB;IACrD,YACC,UAA+B,EAC/B,cAA+B,EAC/B,YAAiD,EACxC,QAAwB;QAEjC,KAAK,CACJ,UAAU,CAAC,qBAAqB,EAChC,UAAU,CAAC,cAAc,EACzB,kBAAkB,EAClB,cAAc,CAAC,OAAO,EACtB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,MAAM,EACrB,YAAY,CACZ,CAAC;QAVO,aAAQ,GAAR,QAAQ,CAAgB;QAYjC,oFAAoF;QACpF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CACjD,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAC5C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9E,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;YAC3D,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;SAClD;IACF,CAAC;IAEM,aAAa,CAAC,OAAuB;;QAC3C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAyC,CAAC;QACvE,QAAQ,YAAY,CAAC,IAAI,EAAE;YAC1B,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;gBACtB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC3C,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,OAAO,EAAE;oBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;wBAC3B,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;qBACrC;iBACD;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,UAAU,CAAC,CAAC;gBAC3B,MAAM,SAAS,GAAG,YAAY,CAAC,OAAwB,CAAC;gBACxD,2DAA2D;gBAC3D,IAAI,SAAS,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE;oBACrC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;iBAC9D;gBACD,MAAM;aACN;YACD,KAAK,UAAU,CAAC,WAAW,CAAC,CAAC;gBAC5B,MAAM,YAAY,GAAG,YAAY,CAAC,OAAiB,CAAC;gBACpD,2DAA2D;gBAC3D,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC,0CAAE,IAAI,MAAK,MAAM,EAAE;oBAC3D,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;iBACzC;gBACD,MAAM;aACN;YACD;gBACC,MAAM;SACP;IACF,CAAC;CACD;AAED;;;;GAIG;AACH,MAAM,UAAU,kCAAkC,CAAC,OAAuB;IACzE,gCAAgC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,EAAE;QAC9B,MAAM,YAAY,GAAG,OAAO,CAAC,OAA6C,CAAC;QAC3E,OAAO,CACN,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK;YACtC,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,UAAU;YAC3C,YAAY,CAAC,IAAI,KAAK,UAAU,CAAC,WAAW,CAC5C,CAAC;KACF;IACD,OAAO,KAAK,CAAC;AACd,CAAC","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\tIProtocolHandler as IBaseProtocolHandler,\n\tIQuorumSnapshot,\n\tProtocolOpHandler,\n} from \"@fluidframework/protocol-base\";\nimport {\n\tIDocumentAttributes,\n\tISignalClient,\n\tISignalMessage,\n} from \"@fluidframework/protocol-definitions\";\n\n// \"term\" was an experimental feature that is being removed. The only safe value to use is 1.\nexport const OnlyValidTermValue = 1 as const;\n\n// ADO: #1986: Start using enum from protocol-base.\nexport enum SignalType {\n\tClientJoin = \"join\", // same value as MessageType.ClientJoin,\n\tClientLeave = \"leave\", // same value as MessageType.ClientLeave,\n\tClear = \"clear\", // used only by client for synthetic signals\n}\n\n/**\n * Function to be used for creating a protocol handler.\n */\nexport type ProtocolHandlerBuilder = (\n\tattributes: IDocumentAttributes,\n\tsnapshot: IQuorumSnapshot,\n\tsendProposal: (key: string, value: any) => number,\n) => IProtocolHandler;\n\nexport interface IProtocolHandler extends IBaseProtocolHandler {\n\treadonly audience: IAudienceOwner;\n\tprocessSignal(message: ISignalMessage);\n}\n\nexport class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandler {\n\tconstructor(\n\t\tattributes: IDocumentAttributes,\n\t\tquorumSnapshot: IQuorumSnapshot,\n\t\tsendProposal: (key: string, value: any) => number,\n\t\treadonly audience: IAudienceOwner,\n\t) {\n\t\tsuper(\n\t\t\tattributes.minimumSequenceNumber,\n\t\t\tattributes.sequenceNumber,\n\t\t\tOnlyValidTermValue,\n\t\t\tquorumSnapshot.members,\n\t\t\tquorumSnapshot.proposals,\n\t\t\tquorumSnapshot.values,\n\t\t\tsendProposal,\n\t\t);\n\n\t\t// Join / leave signals are ignored for \"write\" clients in favor of join / leave ops\n\t\tthis.quorum.on(\"addMember\", (clientId, details) =>\n\t\t\taudience.addMember(clientId, details.client),\n\t\t);\n\t\tthis.quorum.on(\"removeMember\", (clientId) => audience.removeMember(clientId));\n\t\tfor (const [clientId, details] of this.quorum.getMembers()) {\n\t\t\tthis.audience.addMember(clientId, details.client);\n\t\t}\n\t}\n\n\tpublic processSignal(message: ISignalMessage) {\n\t\tconst innerContent = message.content as { content: any; type: string };\n\t\tswitch (innerContent.type) {\n\t\t\tcase SignalType.Clear: {\n\t\t\t\tconst members = this.audience.getMembers();\n\t\t\t\tfor (const [clientId, client] of members) {\n\t\t\t\t\tif (client.mode === \"read\") {\n\t\t\t\t\t\tthis.audience.removeMember(clientId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientJoin: {\n\t\t\t\tconst newClient = innerContent.content as ISignalClient;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (newClient.client.mode === \"read\") {\n\t\t\t\t\tthis.audience.addMember(newClient.clientId, newClient.client);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase SignalType.ClientLeave: {\n\t\t\t\tconst leftClientId = innerContent.content as string;\n\t\t\t\t// Ignore write clients - quorum will control such clients.\n\t\t\t\tif (this.audience.getMember(leftClientId)?.mode === \"read\") {\n\t\t\t\t\tthis.audience.removeMember(leftClientId);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Function to check whether the protocol handler should process the Signal.\n * The protocol handler should strictly handle only ClientJoin, ClientLeave\n * and Clear signal types.\n */\nexport function protocolHandlerShouldProcessSignal(message: ISignalMessage) {\n\t// Signal originates from server\n\tif (message.clientId === null) {\n\t\tconst innerContent = message.content as { content: unknown; type: string };\n\t\treturn (\n\t\t\tinnerContent.type === SignalType.Clear ||\n\t\t\tinnerContent.type === SignalType.ClientJoin ||\n\t\t\tinnerContent.type === SignalType.ClientLeave\n\t\t);\n\t}\n\treturn false;\n}\n"]}
|
package/lib/quorum.d.ts
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { EventForwarder } from "@fluidframework/common-utils";
|
|
6
1
|
import { IFluidCodeDetails } from "@fluidframework/core-interfaces";
|
|
7
|
-
import { ICommittedProposal
|
|
8
|
-
/**
|
|
9
|
-
* Proxies Quorum events.
|
|
10
|
-
*/
|
|
11
|
-
export declare class QuorumProxy extends EventForwarder<IQuorumEvents> implements IQuorum {
|
|
12
|
-
readonly propose: (key: string, value: any) => Promise<void>;
|
|
13
|
-
readonly has: (key: string) => boolean;
|
|
14
|
-
readonly get: (key: string) => any;
|
|
15
|
-
readonly getMembers: () => Map<string, ISequencedClient>;
|
|
16
|
-
readonly getMember: (clientId: string) => ISequencedClient | undefined;
|
|
17
|
-
constructor(quorum: IQuorum);
|
|
18
|
-
}
|
|
2
|
+
import { ICommittedProposal } from "@fluidframework/protocol-definitions";
|
|
19
3
|
export declare function getCodeDetailsFromQuorumValues(quorumValues: [string, ICommittedProposal][]): IFluidCodeDetails;
|
|
20
4
|
export declare function initQuorumValuesFromCodeDetails(source: IFluidCodeDetails): [string, ICommittedProposal][];
|
|
21
5
|
//# sourceMappingURL=quorum.d.ts.map
|
package/lib/quorum.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quorum.d.ts","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"quorum.d.ts","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE1E,wBAAgB,8BAA8B,CAC7C,YAAY,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,GAC1C,iBAAiB,CAKnB;AAED,wBAAgB,+BAA+B,CAC9C,MAAM,EAAE,iBAAiB,GACvB,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAAE,CAUhC"}
|
package/lib/quorum.js
CHANGED
|
@@ -2,22 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { assert
|
|
6
|
-
/**
|
|
7
|
-
* Proxies Quorum events.
|
|
8
|
-
*/
|
|
9
|
-
export class QuorumProxy extends EventForwarder {
|
|
10
|
-
constructor(quorum) {
|
|
11
|
-
super(quorum);
|
|
12
|
-
// This is heavily used object, increase limit at which Node prints warnings.
|
|
13
|
-
super.setMaxListeners(50);
|
|
14
|
-
this.propose = doIfNotDisposed(this, quorum.propose.bind(quorum));
|
|
15
|
-
this.has = doIfNotDisposed(this, quorum.has.bind(quorum));
|
|
16
|
-
this.get = doIfNotDisposed(this, quorum.get.bind(quorum));
|
|
17
|
-
this.getMembers = doIfNotDisposed(this, quorum.getMembers.bind(quorum));
|
|
18
|
-
this.getMember = doIfNotDisposed(this, quorum.getMember.bind(quorum));
|
|
19
|
-
}
|
|
20
|
-
}
|
|
5
|
+
import { assert } from "@fluidframework/common-utils";
|
|
21
6
|
export function getCodeDetailsFromQuorumValues(quorumValues) {
|
|
22
7
|
const qValuesMap = new Map(quorumValues);
|
|
23
8
|
const proposal = qValuesMap.get("code");
|
package/lib/quorum.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quorum.js","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"quorum.js","sourceRoot":"","sources":["../src/quorum.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAItD,MAAM,UAAU,8BAA8B,CAC7C,YAA4C;IAE5C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACxE,OAAO,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,KAA0B,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,+BAA+B,CAC9C,MAAyB;IAEzB,kEAAkE;IAClE,MAAM,qBAAqB,GAAuB;QACjD,GAAG,EAAE,MAAM;QACX,KAAK,EAAE,MAAM;QACb,sBAAsB,EAAE,CAAC;QACzB,oBAAoB,EAAE,CAAC;QACvB,cAAc,EAAE,CAAC;KACjB,CAAC;IACF,OAAO,CAAC,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { assert } from \"@fluidframework/common-utils\";\nimport { IFluidCodeDetails } from \"@fluidframework/core-interfaces\";\nimport { ICommittedProposal } from \"@fluidframework/protocol-definitions\";\n\nexport function getCodeDetailsFromQuorumValues(\n\tquorumValues: [string, ICommittedProposal][],\n): IFluidCodeDetails {\n\tconst qValuesMap = new Map(quorumValues);\n\tconst proposal = qValuesMap.get(\"code\");\n\tassert(proposal !== undefined, 0x2dc /* \"Cannot find code proposal\" */);\n\treturn proposal?.value as IFluidCodeDetails;\n}\n\nexport function initQuorumValuesFromCodeDetails(\n\tsource: IFluidCodeDetails,\n): [string, ICommittedProposal][] {\n\t// Seed the base quorum to be an empty list with a code quorum set\n\tconst committedCodeProposal: ICommittedProposal = {\n\t\tkey: \"code\",\n\t\tvalue: source,\n\t\tapprovalSequenceNumber: 0,\n\t\tcommitSequenceNumber: 0,\n\t\tsequenceNumber: 0,\n\t};\n\treturn [[\"code\", committedCodeProposal]];\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/container-loader",
|
|
3
|
-
"version": "2.0.0-internal.5.
|
|
3
|
+
"version": "2.0.0-internal.5.3.1",
|
|
4
4
|
"description": "Fluid container loader",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
39
39
|
"@fluidframework/common-utils": "^1.1.1",
|
|
40
|
-
"@fluidframework/container-definitions": ">=2.0.0-internal.5.
|
|
41
|
-
"@fluidframework/container-utils": ">=2.0.0-internal.5.
|
|
42
|
-
"@fluidframework/core-interfaces": ">=2.0.0-internal.5.
|
|
43
|
-
"@fluidframework/driver-definitions": ">=2.0.0-internal.5.
|
|
44
|
-
"@fluidframework/driver-utils": ">=2.0.0-internal.5.
|
|
40
|
+
"@fluidframework/container-definitions": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
41
|
+
"@fluidframework/container-utils": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
42
|
+
"@fluidframework/core-interfaces": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
43
|
+
"@fluidframework/driver-definitions": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
44
|
+
"@fluidframework/driver-utils": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
45
45
|
"@fluidframework/protocol-base": "^0.1039.1000",
|
|
46
46
|
"@fluidframework/protocol-definitions": "^1.1.0",
|
|
47
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-internal.5.
|
|
47
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
48
48
|
"abort-controller": "^3.0.0",
|
|
49
49
|
"double-ended-queue": "^2.1.0-0",
|
|
50
50
|
"events": "^3.1.0",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
"uuid": "^8.3.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@fluid-internal/test-loader-utils": ">=2.0.0-internal.5.
|
|
57
|
-
"@fluid-tools/build-cli": "^0.
|
|
56
|
+
"@fluid-internal/test-loader-utils": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
57
|
+
"@fluid-tools/build-cli": "^0.21.0",
|
|
58
58
|
"@fluidframework/build-common": "^1.2.0",
|
|
59
|
-
"@fluidframework/build-tools": "^0.
|
|
60
|
-
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.5.
|
|
59
|
+
"@fluidframework/build-tools": "^0.21.0",
|
|
60
|
+
"@fluidframework/container-loader-previous": "npm:@fluidframework/container-loader@2.0.0-internal.5.2.0",
|
|
61
61
|
"@fluidframework/eslint-config-fluid": "^2.0.0",
|
|
62
|
-
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.
|
|
62
|
+
"@fluidframework/mocha-test-setup": ">=2.0.0-internal.5.3.1 <2.0.0-internal.5.4.0",
|
|
63
63
|
"@microsoft/api-extractor": "^7.34.4",
|
|
64
64
|
"@types/double-ended-queue": "^2.1.0",
|
|
65
65
|
"@types/events": "^3.0.0",
|
|
@@ -82,7 +82,11 @@
|
|
|
82
82
|
"typescript": "~4.5.5"
|
|
83
83
|
},
|
|
84
84
|
"typeValidation": {
|
|
85
|
-
"broken": {
|
|
85
|
+
"broken": {
|
|
86
|
+
"InterfaceDeclaration_IContainerExperimental": {
|
|
87
|
+
"backCompat": false
|
|
88
|
+
}
|
|
89
|
+
}
|
|
86
90
|
},
|
|
87
91
|
"scripts": {
|
|
88
92
|
"build": "fluid-build . --task build",
|
|
@@ -109,6 +113,6 @@
|
|
|
109
113
|
"tsc": "tsc",
|
|
110
114
|
"tsc:watch": "tsc --watch",
|
|
111
115
|
"typetests:gen": "fluid-type-test-generator",
|
|
112
|
-
"typetests:prepare": "flub
|
|
116
|
+
"typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
|
|
113
117
|
}
|
|
114
118
|
}
|
package/src/connectionManager.ts
CHANGED
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { default as AbortController } from "abort-controller";
|
|
7
|
-
import { ITelemetryProperties } from "@fluidframework/
|
|
8
|
-
import { IDisposable } from "@fluidframework/core-interfaces";
|
|
7
|
+
import { IDisposable, ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
9
8
|
import { assert, performance, TypedEventEmitter } from "@fluidframework/common-utils";
|
|
10
9
|
import {
|
|
11
10
|
IDeltaQueue,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ITelemetryProperties, TelemetryEventCategory } from "@fluidframework/
|
|
6
|
+
import { ITelemetryProperties, TelemetryEventCategory } from "@fluidframework/core-interfaces";
|
|
7
7
|
import { assert, Timer } from "@fluidframework/common-utils";
|
|
8
8
|
import { IConnectionDetailsInternal, IDeltaManager } from "@fluidframework/container-definitions";
|
|
9
9
|
import { IAnyDriverError } from "@fluidframework/driver-definitions";
|
package/src/container.ts
CHANGED
|
@@ -7,18 +7,21 @@
|
|
|
7
7
|
import merge from "lodash/merge";
|
|
8
8
|
|
|
9
9
|
import { v4 as uuid } from "uuid";
|
|
10
|
-
import {
|
|
11
|
-
IEvent,
|
|
12
|
-
ITelemetryProperties,
|
|
13
|
-
TelemetryEventCategory,
|
|
14
|
-
} from "@fluidframework/common-definitions";
|
|
10
|
+
import { IEvent } from "@fluidframework/common-definitions";
|
|
15
11
|
import {
|
|
16
12
|
TypedEventEmitter,
|
|
17
13
|
assert,
|
|
18
14
|
performance,
|
|
19
15
|
unreachableCase,
|
|
20
16
|
} from "@fluidframework/common-utils";
|
|
21
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
ITelemetryProperties,
|
|
19
|
+
TelemetryEventCategory,
|
|
20
|
+
IRequest,
|
|
21
|
+
IResponse,
|
|
22
|
+
IFluidRouter,
|
|
23
|
+
FluidObject,
|
|
24
|
+
} from "@fluidframework/core-interfaces";
|
|
22
25
|
import {
|
|
23
26
|
IAudience,
|
|
24
27
|
IConnectionDetailsInternal,
|
|
@@ -98,7 +101,6 @@ import { Audience } from "./audience";
|
|
|
98
101
|
import { ContainerContext } from "./containerContext";
|
|
99
102
|
import { ReconnectMode, IConnectionManagerFactoryArgs, getPackageName } from "./contracts";
|
|
100
103
|
import { DeltaManager, IConnectionArgs } from "./deltaManager";
|
|
101
|
-
import { DeltaManagerProxy } from "./deltaManagerProxy";
|
|
102
104
|
import { IDetachedBlobStorage, ILoaderOptions, RelativeLoader } from "./loader";
|
|
103
105
|
import { pkgVersion } from "./packageVersion";
|
|
104
106
|
import {
|
|
@@ -109,19 +111,16 @@ import {
|
|
|
109
111
|
} from "./containerStorageAdapter";
|
|
110
112
|
import { IConnectionStateHandler, createConnectionStateHandler } from "./connectionStateHandler";
|
|
111
113
|
import { getProtocolSnapshotTree, getSnapshotTreeFromSerializedContainer } from "./utils";
|
|
112
|
-
import {
|
|
113
|
-
initQuorumValuesFromCodeDetails,
|
|
114
|
-
getCodeDetailsFromQuorumValues,
|
|
115
|
-
QuorumProxy,
|
|
116
|
-
} from "./quorum";
|
|
114
|
+
import { initQuorumValuesFromCodeDetails, getCodeDetailsFromQuorumValues } from "./quorum";
|
|
117
115
|
import { NoopHeuristic } from "./noopHeuristic";
|
|
118
116
|
import { ConnectionManager } from "./connectionManager";
|
|
119
117
|
import { ConnectionState } from "./connectionState";
|
|
120
118
|
import {
|
|
121
|
-
OnlyValidTermValue,
|
|
122
119
|
IProtocolHandler,
|
|
120
|
+
OnlyValidTermValue,
|
|
123
121
|
ProtocolHandler,
|
|
124
122
|
ProtocolHandlerBuilder,
|
|
123
|
+
protocolHandlerShouldProcessSignal,
|
|
125
124
|
} from "./protocol";
|
|
126
125
|
|
|
127
126
|
const detachedContainerRefSeqNumber = 0;
|
|
@@ -794,7 +793,10 @@ export class Container
|
|
|
794
793
|
// dmLastMsqSeqNumber: if present, same as dmLastProcessedSeqNumber
|
|
795
794
|
dmLastMsqSeqNumber: () => this.deltaManager?.lastMessage?.sequenceNumber,
|
|
796
795
|
dmLastMsqSeqTimestamp: () => this.deltaManager?.lastMessage?.timestamp,
|
|
797
|
-
dmLastMsqSeqClientId: () =>
|
|
796
|
+
dmLastMsqSeqClientId: () =>
|
|
797
|
+
this.deltaManager?.lastMessage?.clientId === null
|
|
798
|
+
? "null"
|
|
799
|
+
: this.deltaManager?.lastMessage?.clientId,
|
|
798
800
|
dmLastMsgClientSeq: () => this.deltaManager?.lastMessage?.clientSequenceNumber,
|
|
799
801
|
connectionStateDuration: () =>
|
|
800
802
|
performance.now() - this.connectionTransitionTimes[this.connectionState],
|
|
@@ -985,6 +987,11 @@ export class Container
|
|
|
985
987
|
}
|
|
986
988
|
} finally {
|
|
987
989
|
this._lifecycleState = "closed";
|
|
990
|
+
|
|
991
|
+
// There is no user for summarizer, so we need to ensure dispose is called
|
|
992
|
+
if (this.client.details.type === summarizerClientType) {
|
|
993
|
+
this.dispose(error);
|
|
994
|
+
}
|
|
988
995
|
}
|
|
989
996
|
}
|
|
990
997
|
|
|
@@ -1057,6 +1064,11 @@ export class Container
|
|
|
1057
1064
|
if (!this.offlineLoadEnabled) {
|
|
1058
1065
|
throw new UsageError("Can't get pending local state unless offline load is enabled");
|
|
1059
1066
|
}
|
|
1067
|
+
if (this.closed || this._disposed) {
|
|
1068
|
+
throw new UsageError(
|
|
1069
|
+
"Pending state cannot be retried if the container is closed or disposed",
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1060
1072
|
assert(
|
|
1061
1073
|
this.attachState === AttachState.Attached,
|
|
1062
1074
|
0x0d1 /* "Container should be attached before close" */,
|
|
@@ -1996,7 +2008,11 @@ export class Container
|
|
|
1996
2008
|
} else if (value === ConnectionState.CatchingUp) {
|
|
1997
2009
|
// This info is of most interesting while Catching Up.
|
|
1998
2010
|
checkpointSequenceNumber = this.deltaManager.lastKnownSeqNumber;
|
|
1999
|
-
|
|
2011
|
+
// Need to check that we have already loaded and fetched the snapshot.
|
|
2012
|
+
if (
|
|
2013
|
+
this.deltaManager.hasCheckpointSequenceNumber &&
|
|
2014
|
+
this._lifecycleState === "loaded"
|
|
2015
|
+
) {
|
|
2000
2016
|
opsBehind = checkpointSequenceNumber - this.deltaManager.lastSequenceNumber;
|
|
2001
2017
|
}
|
|
2002
2018
|
}
|
|
@@ -2230,7 +2246,7 @@ export class Container
|
|
|
2230
2246
|
|
|
2231
2247
|
private processSignal(message: ISignalMessage) {
|
|
2232
2248
|
// No clientId indicates a system signal message.
|
|
2233
|
-
if (message
|
|
2249
|
+
if (protocolHandlerShouldProcessSignal(message)) {
|
|
2234
2250
|
this.protocolHandler.processSignal(message);
|
|
2235
2251
|
} else {
|
|
2236
2252
|
const local = this.clientId === message.clientId;
|
|
@@ -2307,17 +2323,18 @@ export class Container
|
|
|
2307
2323
|
throw new Error(packageNotFactoryError);
|
|
2308
2324
|
}
|
|
2309
2325
|
|
|
2310
|
-
const
|
|
2311
|
-
|
|
2326
|
+
const getSpecifiedCodeDetails = () =>
|
|
2327
|
+
(this.protocolHandler.quorum.get("code") ??
|
|
2328
|
+
this.protocolHandler.quorum.get("code2")) as IFluidCodeDetails | undefined;
|
|
2312
2329
|
|
|
2313
2330
|
const context = new ContainerContext(
|
|
2314
2331
|
this.options,
|
|
2315
2332
|
this.scope,
|
|
2316
2333
|
snapshot,
|
|
2317
2334
|
this._loadedFromVersion,
|
|
2318
|
-
|
|
2335
|
+
this._deltaManager,
|
|
2319
2336
|
this.storageAdapter,
|
|
2320
|
-
|
|
2337
|
+
this.protocolHandler.quorum,
|
|
2321
2338
|
this.protocolHandler.audience,
|
|
2322
2339
|
loader,
|
|
2323
2340
|
(type, contents, batch, metadata) =>
|
|
@@ -2333,9 +2350,10 @@ export class Container
|
|
|
2333
2350
|
this.getAbsoluteUrl,
|
|
2334
2351
|
() => this.resolvedUrl?.id,
|
|
2335
2352
|
() => this.clientId,
|
|
2336
|
-
() =>
|
|
2353
|
+
() => this._deltaManager.serviceConfiguration,
|
|
2337
2354
|
() => this.attachState,
|
|
2338
2355
|
() => this.connected,
|
|
2356
|
+
getSpecifiedCodeDetails,
|
|
2339
2357
|
this._deltaManager.clientDetails,
|
|
2340
2358
|
existing,
|
|
2341
2359
|
this.subLogger,
|
|
@@ -2343,8 +2361,6 @@ export class Container
|
|
|
2343
2361
|
);
|
|
2344
2362
|
this._lifecycleEvents.once("disposed", () => {
|
|
2345
2363
|
context.dispose();
|
|
2346
|
-
quorumProxy.dispose();
|
|
2347
|
-
deltaManagerProxy.dispose();
|
|
2348
2364
|
});
|
|
2349
2365
|
|
|
2350
2366
|
this._runtime = await PerformanceEvent.timedExecAsync(
|
|
@@ -2388,7 +2404,7 @@ export class Container
|
|
|
2388
2404
|
|
|
2389
2405
|
/**
|
|
2390
2406
|
* IContainer interface that includes experimental features still under development.
|
|
2391
|
-
* @
|
|
2407
|
+
* @experimental
|
|
2392
2408
|
*/
|
|
2393
2409
|
export interface IContainerExperimental extends IContainer {
|
|
2394
2410
|
/**
|
|
@@ -2399,5 +2415,13 @@ export interface IContainerExperimental extends IContainer {
|
|
|
2399
2415
|
* @experimental misuse of this API can result in duplicate op submission and potential document corruption
|
|
2400
2416
|
* {@link https://github.com/microsoft/FluidFramework/blob/main/packages/loader/container-loader/closeAndGetPendingLocalState.md}
|
|
2401
2417
|
*/
|
|
2402
|
-
getPendingLocalState(): string;
|
|
2418
|
+
getPendingLocalState?(): string;
|
|
2419
|
+
|
|
2420
|
+
/**
|
|
2421
|
+
* Closes the container and returns serialized local state intended to be
|
|
2422
|
+
* given to a newly loaded container.
|
|
2423
|
+
* @experimental
|
|
2424
|
+
* {@link https://github.com/microsoft/FluidFramework/blob/main/packages/loader/container-loader/closeAndGetPendingLocalState.md}
|
|
2425
|
+
*/
|
|
2426
|
+
closeAndGetPendingLocalState(): string;
|
|
2403
2427
|
}
|
package/src/containerContext.ts
CHANGED
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
IClientConfiguration,
|
|
22
22
|
IClientDetails,
|
|
23
23
|
IDocumentMessage,
|
|
24
|
-
IQuorum,
|
|
25
24
|
IQuorumClients,
|
|
26
25
|
ISequencedDocumentMessage,
|
|
27
26
|
ISnapshotTree,
|
|
@@ -72,10 +71,6 @@ export class ContainerContext implements IContainerContext {
|
|
|
72
71
|
return this._disposed;
|
|
73
72
|
}
|
|
74
73
|
|
|
75
|
-
public get quorum(): IQuorumClients {
|
|
76
|
-
return this._quorum;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
74
|
constructor(
|
|
80
75
|
public readonly options: ILoaderOptions,
|
|
81
76
|
public readonly scope: FluidObject,
|
|
@@ -83,7 +78,7 @@ export class ContainerContext implements IContainerContext {
|
|
|
83
78
|
private readonly _version: IVersion | undefined,
|
|
84
79
|
public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
|
85
80
|
public readonly storage: IDocumentStorageService,
|
|
86
|
-
|
|
81
|
+
public readonly quorum: IQuorumClients,
|
|
87
82
|
public readonly audience: IAudience,
|
|
88
83
|
public readonly loader: ILoader,
|
|
89
84
|
public readonly submitFn: (
|
|
@@ -111,24 +106,13 @@ export class ContainerContext implements IContainerContext {
|
|
|
111
106
|
private readonly _getServiceConfiguration: () => IClientConfiguration | undefined,
|
|
112
107
|
private readonly _getAttachState: () => AttachState,
|
|
113
108
|
private readonly _getConnected: () => boolean,
|
|
109
|
+
public readonly getSpecifiedCodeDetails: () => IFluidCodeDetails | undefined,
|
|
114
110
|
public readonly clientDetails: IClientDetails,
|
|
115
111
|
public readonly existing: boolean,
|
|
116
112
|
public readonly taggedLogger: ITelemetryLoggerExt,
|
|
117
113
|
public readonly pendingLocalState?: unknown,
|
|
118
114
|
) {}
|
|
119
115
|
|
|
120
|
-
/**
|
|
121
|
-
* @deprecated Temporary migratory API, to be removed when customers no longer need it.
|
|
122
|
-
* When removed, `ContainerContext` should only take an {@link @fluidframework/container-definitions#IQuorumClients}
|
|
123
|
-
* rather than an {@link @fluidframework/protocol-definitions#IQuorum}.
|
|
124
|
-
* See {@link @fluidframework/container-definitions#IContainerContext} for more details.
|
|
125
|
-
*/
|
|
126
|
-
public getSpecifiedCodeDetails(): IFluidCodeDetails | undefined {
|
|
127
|
-
return (this._quorum.get("code") ?? this._quorum.get("code2")) as
|
|
128
|
-
| IFluidCodeDetails
|
|
129
|
-
| undefined;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
116
|
public dispose(error?: Error): void {
|
|
133
117
|
this._disposed = true;
|
|
134
118
|
}
|
|
@@ -229,6 +229,14 @@ class BlobOnlyStorage implements IDocumentStorageService {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
+
// runtime will write a tree to the summary containing "attachment" type entries
|
|
233
|
+
// which reference attachment blobs by ID, along with a blob containing the blob redirect table.
|
|
234
|
+
// However, some drivers do not support the "attachment" type and will convert them to "blob" type
|
|
235
|
+
// entries. We want to avoid saving these to reduce the size of stashed change blobs, but we
|
|
236
|
+
// need to make sure the blob redirect table is saved.
|
|
237
|
+
const blobsTreeName = ".blobs";
|
|
238
|
+
const redirectTableBlobName = ".redirectTable";
|
|
239
|
+
|
|
232
240
|
/**
|
|
233
241
|
* Get blob contents of a snapshot tree from storage (or, ideally, cache)
|
|
234
242
|
*/
|
|
@@ -245,10 +253,15 @@ async function getBlobContentsFromTreeCore(
|
|
|
245
253
|
tree: ISnapshotTree,
|
|
246
254
|
blobs: ISerializableBlobContents,
|
|
247
255
|
storage: IDocumentStorageService,
|
|
256
|
+
root = true,
|
|
248
257
|
) {
|
|
249
258
|
const treePs: Promise<any>[] = [];
|
|
250
|
-
for (const subTree of Object.
|
|
251
|
-
|
|
259
|
+
for (const [key, subTree] of Object.entries(tree.trees)) {
|
|
260
|
+
if (root && key === blobsTreeName) {
|
|
261
|
+
treePs.push(getBlobManagerTreeFromTree(subTree, blobs, storage));
|
|
262
|
+
} else {
|
|
263
|
+
treePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));
|
|
264
|
+
}
|
|
252
265
|
}
|
|
253
266
|
for (const id of Object.values(tree.blobs)) {
|
|
254
267
|
const blob = await storage.readBlob(id);
|
|
@@ -258,6 +271,18 @@ async function getBlobContentsFromTreeCore(
|
|
|
258
271
|
return Promise.all(treePs);
|
|
259
272
|
}
|
|
260
273
|
|
|
274
|
+
// save redirect table from .blobs tree but nothing else
|
|
275
|
+
async function getBlobManagerTreeFromTree(
|
|
276
|
+
tree: ISnapshotTree,
|
|
277
|
+
blobs: ISerializableBlobContents,
|
|
278
|
+
storage: IDocumentStorageService,
|
|
279
|
+
) {
|
|
280
|
+
const id = tree.blobs[redirectTableBlobName];
|
|
281
|
+
const blob = await storage.readBlob(id);
|
|
282
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
283
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
284
|
+
}
|
|
285
|
+
|
|
261
286
|
/**
|
|
262
287
|
* Extract blob contents from a snapshot tree with blob contents
|
|
263
288
|
*/
|
|
@@ -272,9 +297,14 @@ export function getBlobContentsFromTreeWithBlobContents(
|
|
|
272
297
|
function getBlobContentsFromTreeWithBlobContentsCore(
|
|
273
298
|
tree: ISnapshotTreeWithBlobContents,
|
|
274
299
|
blobs: ISerializableBlobContents,
|
|
300
|
+
root = true,
|
|
275
301
|
) {
|
|
276
|
-
for (const subTree of Object.
|
|
277
|
-
|
|
302
|
+
for (const [key, subTree] of Object.entries(tree.trees)) {
|
|
303
|
+
if (root && key === blobsTreeName) {
|
|
304
|
+
getBlobManagerTreeFromTreeWithBlobContents(subTree, blobs);
|
|
305
|
+
} else {
|
|
306
|
+
getBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);
|
|
307
|
+
}
|
|
278
308
|
}
|
|
279
309
|
for (const id of Object.values(tree.blobs)) {
|
|
280
310
|
const blob = tree.blobsContents[id];
|
|
@@ -283,3 +313,15 @@ function getBlobContentsFromTreeWithBlobContentsCore(
|
|
|
283
313
|
blobs[id] = bufferToString(blob, "utf8");
|
|
284
314
|
}
|
|
285
315
|
}
|
|
316
|
+
|
|
317
|
+
// save redirect table from .blobs tree but nothing else
|
|
318
|
+
function getBlobManagerTreeFromTreeWithBlobContents(
|
|
319
|
+
tree: ISnapshotTreeWithBlobContents,
|
|
320
|
+
blobs: ISerializableBlobContents,
|
|
321
|
+
) {
|
|
322
|
+
const id = tree.blobs[redirectTableBlobName];
|
|
323
|
+
const blob = tree.blobsContents[id];
|
|
324
|
+
assert(blob !== undefined, 0x70f /* Blob must be present in blobsContents */);
|
|
325
|
+
// ArrayBufferLike will not survive JSON.stringify()
|
|
326
|
+
blobs[id] = bufferToString(blob, "utf8");
|
|
327
|
+
}
|
package/src/contracts.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { ITelemetryProperties } from "@fluidframework/
|
|
6
|
+
import { ITelemetryProperties } from "@fluidframework/core-interfaces";
|
|
7
7
|
import {
|
|
8
8
|
IDeltaQueue,
|
|
9
9
|
ReadOnlyInfo,
|
|
@@ -148,8 +148,6 @@ 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.
|
|
153
151
|
*/
|
|
154
152
|
readonly pongHandler: (latency: number) => void;
|
|
155
153
|
|
package/src/deltaManager.ts
CHANGED
|
@@ -5,11 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { default as AbortController } from "abort-controller";
|
|
7
7
|
import { v4 as uuid } from "uuid";
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
ITelemetryProperties,
|
|
11
|
-
ITelemetryErrorEvent,
|
|
12
|
-
} from "@fluidframework/common-definitions";
|
|
8
|
+
import { IEventProvider } from "@fluidframework/common-definitions";
|
|
9
|
+
import { ITelemetryProperties, ITelemetryErrorEvent } from "@fluidframework/core-interfaces";
|
|
13
10
|
import {
|
|
14
11
|
IDeltaHandlerStrategy,
|
|
15
12
|
IDeltaManager,
|
|
@@ -70,6 +67,13 @@ export interface IDeltaManagerInternalEvents extends IDeltaManagerEvents {
|
|
|
70
67
|
(event: "cancelEstablishingConnection", listener: (reason: string) => void);
|
|
71
68
|
}
|
|
72
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Batching makes assumptions about what might be on the metadata. This interface codifies those assumptions, but does not validate them.
|
|
72
|
+
*/
|
|
73
|
+
interface IBatchMetadata {
|
|
74
|
+
batch?: boolean;
|
|
75
|
+
}
|
|
76
|
+
|
|
73
77
|
/**
|
|
74
78
|
* Determines if message was sent by client, not service
|
|
75
79
|
*/
|
|
@@ -293,13 +297,16 @@ export class DeltaManager<TConnectionManager extends IConnectionManager>
|
|
|
293
297
|
|
|
294
298
|
if (batch.length === 1) {
|
|
295
299
|
assert(
|
|
296
|
-
batch[0].metadata?.batch === undefined,
|
|
300
|
+
(batch[0].metadata as IBatchMetadata)?.batch === undefined,
|
|
297
301
|
0x3c9 /* no batch markup on single message */,
|
|
298
302
|
);
|
|
299
303
|
} else {
|
|
300
|
-
assert(batch[0].metadata?.batch === true, 0x3ca /* no start batch markup */);
|
|
301
304
|
assert(
|
|
302
|
-
batch[
|
|
305
|
+
(batch[0].metadata as IBatchMetadata)?.batch === true,
|
|
306
|
+
0x3ca /* no start batch markup */,
|
|
307
|
+
);
|
|
308
|
+
assert(
|
|
309
|
+
(batch[batch.length - 1].metadata as IBatchMetadata)?.batch === false,
|
|
303
310
|
0x3cb /* no end batch markup */,
|
|
304
311
|
);
|
|
305
312
|
}
|
package/src/disposal.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IDisposable } from "@fluidframework/common-definitions";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Returns a wrapper around the provided function, which will only invoke the inner function if the provided
|
|
10
|
+
* {@link @fluidframework/common-definitions#IDisposable | disposable} object has not yet been disposed.
|
|
11
|
+
*
|
|
12
|
+
* @throws Will throw an error if the item has already been disposed.
|
|
13
|
+
*/
|
|
14
|
+
export function doIfNotDisposed<T>(
|
|
15
|
+
disposable: IDisposable,
|
|
16
|
+
f: (...args: any[]) => T,
|
|
17
|
+
): (...args: any[]) => T {
|
|
18
|
+
return (...args: any[]): T => {
|
|
19
|
+
if (disposable.disposed) {
|
|
20
|
+
throw new Error("Already disposed");
|
|
21
|
+
} else {
|
|
22
|
+
return f(...args);
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
package/src/loader.ts
CHANGED
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { v4 as uuid } from "uuid";
|
|
7
|
-
import { ITelemetryBaseLogger } from "@fluidframework/common-definitions";
|
|
8
7
|
import {
|
|
9
8
|
ITelemetryLoggerExt,
|
|
10
9
|
ChildLogger,
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
sessionStorageConfigProvider,
|
|
18
17
|
} from "@fluidframework/telemetry-utils";
|
|
19
18
|
import {
|
|
19
|
+
ITelemetryBaseLogger,
|
|
20
20
|
FluidObject,
|
|
21
21
|
IFluidRouter,
|
|
22
22
|
IRequest,
|
package/src/packageVersion.ts
CHANGED
package/src/protocol.ts
CHANGED
|
@@ -99,3 +99,21 @@ export class ProtocolHandler extends ProtocolOpHandler implements IProtocolHandl
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Function to check whether the protocol handler should process the Signal.
|
|
105
|
+
* The protocol handler should strictly handle only ClientJoin, ClientLeave
|
|
106
|
+
* and Clear signal types.
|
|
107
|
+
*/
|
|
108
|
+
export function protocolHandlerShouldProcessSignal(message: ISignalMessage) {
|
|
109
|
+
// Signal originates from server
|
|
110
|
+
if (message.clientId === null) {
|
|
111
|
+
const innerContent = message.content as { content: unknown; type: string };
|
|
112
|
+
return (
|
|
113
|
+
innerContent.type === SignalType.Clear ||
|
|
114
|
+
innerContent.type === SignalType.ClientJoin ||
|
|
115
|
+
innerContent.type === SignalType.ClientLeave
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|