@fluidframework/container-loader 2.0.0-dev-rc.1.0.0.225277 → 2.0.0-dev-rc.1.0.0.232845
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 +34 -0
- package/README.md +3 -9
- package/api-report/container-loader.api.md +1 -1
- package/dist/attachment.d.ts +116 -0
- package/dist/attachment.d.ts.map +1 -0
- package/dist/attachment.js +82 -0
- package/dist/attachment.js.map +1 -0
- package/dist/{audience.cjs → audience.js} +1 -1
- package/dist/audience.js.map +1 -0
- package/dist/{catchUpMonitor.cjs → catchUpMonitor.js} +1 -1
- package/dist/catchUpMonitor.js.map +1 -0
- package/dist/connectionManager.d.ts.map +1 -1
- package/dist/{connectionManager.cjs → connectionManager.js} +6 -7
- package/dist/connectionManager.js.map +1 -0
- package/dist/connectionState.d.ts +1 -1
- package/dist/{connectionState.cjs → connectionState.js} +2 -2
- package/dist/{connectionState.cjs.map → connectionState.js.map} +1 -1
- package/dist/{connectionStateHandler.cjs → connectionStateHandler.js} +3 -3
- package/dist/connectionStateHandler.js.map +1 -0
- package/dist/container-loader-alpha.d.ts +2 -2
- package/dist/container-loader-beta.d.ts +24 -1
- package/dist/container-loader-public.d.ts +24 -1
- package/dist/container-loader-untrimmed.d.ts +2 -2
- package/dist/container.d.ts +21 -8
- package/dist/container.d.ts.map +1 -1
- package/dist/{container.cjs → container.js} +192 -164
- package/dist/container.js.map +1 -0
- package/dist/containerContext.d.ts +3 -2
- package/dist/containerContext.d.ts.map +1 -1
- package/dist/{containerContext.cjs → containerContext.js} +3 -2
- package/dist/containerContext.js.map +1 -0
- package/dist/containerStorageAdapter.d.ts +3 -3
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/{containerStorageAdapter.cjs → containerStorageAdapter.js} +13 -14
- package/dist/containerStorageAdapter.js.map +1 -0
- package/dist/{contracts.cjs → contracts.js} +1 -1
- package/dist/contracts.js.map +1 -0
- package/dist/{debugLogger.cjs → debugLogger.js} +1 -1
- package/dist/debugLogger.js.map +1 -0
- package/dist/{deltaManager.cjs → deltaManager.js} +3 -3
- package/dist/deltaManager.js.map +1 -0
- package/dist/{deltaQueue.cjs → deltaQueue.js} +1 -1
- package/dist/deltaQueue.js.map +1 -0
- package/dist/{disposal.cjs → disposal.js} +1 -1
- package/dist/disposal.js.map +1 -0
- package/dist/{error.cjs → error.js} +1 -1
- package/dist/error.js.map +1 -0
- package/dist/{index.cjs → index.js} +6 -6
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +1 -1
- package/dist/{loader.cjs → loader.js} +5 -5
- package/dist/{loader.cjs.map → loader.js.map} +1 -1
- package/dist/location-redirection-utilities/{index.cjs → index.js} +2 -2
- package/dist/location-redirection-utilities/index.js.map +1 -0
- package/dist/location-redirection-utilities/{resolveWithLocationRedirection.cjs → resolveWithLocationRedirection.js} +1 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -0
- package/dist/{noopHeuristic.cjs → noopHeuristic.js} +1 -1
- package/dist/noopHeuristic.js.map +1 -0
- package/dist/packageVersion.d.ts +1 -1
- package/dist/{packageVersion.cjs → packageVersion.js} +2 -2
- package/dist/packageVersion.js.map +1 -0
- package/dist/{protocol.cjs → protocol.js} +1 -1
- package/dist/protocol.js.map +1 -0
- package/dist/protocolTreeDocumentStorageService.d.ts +1 -0
- package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
- package/dist/{protocolTreeDocumentStorageService.cjs → protocolTreeDocumentStorageService.js} +2 -1
- package/dist/protocolTreeDocumentStorageService.js.map +1 -0
- package/dist/{quorum.cjs → quorum.js} +1 -1
- package/dist/quorum.js.map +1 -0
- package/dist/retriableDocumentStorageService.d.ts +2 -1
- package/dist/retriableDocumentStorageService.d.ts.map +1 -1
- package/dist/{retriableDocumentStorageService.cjs → retriableDocumentStorageService.js} +9 -1
- package/dist/retriableDocumentStorageService.js.map +1 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/utils.d.ts +13 -7
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +211 -0
- package/dist/utils.js.map +1 -0
- package/lib/attachment.d.mts +112 -0
- package/lib/attachment.d.mts.map +1 -0
- package/lib/attachment.mjs +74 -0
- package/lib/attachment.mjs.map +1 -0
- package/lib/connectionManager.d.mts.map +1 -1
- package/lib/connectionManager.mjs +2 -5
- package/lib/connectionManager.mjs.map +1 -1
- package/lib/connectionState.d.mts +1 -1
- package/lib/connectionState.mjs +1 -1
- package/lib/connectionState.mjs.map +1 -1
- package/lib/container-loader-alpha.d.mts +2 -2
- package/lib/container-loader-beta.d.mts +24 -1
- package/lib/container-loader-public.d.mts +24 -1
- package/lib/container-loader-untrimmed.d.mts +2 -2
- package/lib/container.d.mts +21 -8
- package/lib/container.d.mts.map +1 -1
- package/lib/container.mjs +176 -151
- package/lib/container.mjs.map +1 -1
- package/lib/containerContext.d.mts +3 -2
- package/lib/containerContext.d.mts.map +1 -1
- package/lib/containerContext.mjs +2 -1
- package/lib/containerContext.mjs.map +1 -1
- package/lib/containerStorageAdapter.d.mts +3 -3
- package/lib/containerStorageAdapter.d.mts.map +1 -1
- package/lib/containerStorageAdapter.mjs +10 -11
- package/lib/containerStorageAdapter.mjs.map +1 -1
- package/lib/loader.d.mts +1 -1
- package/lib/loader.mjs.map +1 -1
- package/lib/packageVersion.d.mts +1 -1
- package/lib/packageVersion.mjs +1 -1
- package/lib/packageVersion.mjs.map +1 -1
- package/lib/protocolTreeDocumentStorageService.d.mts +1 -0
- package/lib/protocolTreeDocumentStorageService.d.mts.map +1 -1
- package/lib/protocolTreeDocumentStorageService.mjs +1 -0
- package/lib/protocolTreeDocumentStorageService.mjs.map +1 -1
- package/lib/retriableDocumentStorageService.d.mts +2 -1
- package/lib/retriableDocumentStorageService.d.mts.map +1 -1
- package/lib/retriableDocumentStorageService.mjs +9 -1
- package/lib/retriableDocumentStorageService.mjs.map +1 -1
- package/lib/utils.d.mts +13 -7
- package/lib/utils.d.mts.map +1 -1
- package/lib/utils.mjs +96 -29
- package/lib/utils.mjs.map +1 -1
- package/package.json +36 -30
- package/src/attachment.ts +219 -0
- package/src/connectionManager.ts +2 -4
- package/src/connectionState.ts +1 -1
- package/src/container.ts +260 -191
- package/src/containerContext.ts +2 -1
- package/src/containerStorageAdapter.ts +15 -12
- package/src/loader.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/protocolTreeDocumentStorageService.ts +1 -0
- package/src/retriableDocumentStorageService.ts +18 -1
- package/src/utils.ts +128 -36
- package/dist/audience.cjs.map +0 -1
- package/dist/catchUpMonitor.cjs.map +0 -1
- package/dist/connectionManager.cjs.map +0 -1
- package/dist/connectionStateHandler.cjs.map +0 -1
- package/dist/container.cjs.map +0 -1
- package/dist/containerContext.cjs.map +0 -1
- package/dist/containerStorageAdapter.cjs.map +0 -1
- package/dist/contracts.cjs.map +0 -1
- package/dist/debugLogger.cjs.map +0 -1
- package/dist/deltaManager.cjs.map +0 -1
- package/dist/deltaQueue.cjs.map +0 -1
- package/dist/disposal.cjs.map +0 -1
- package/dist/error.cjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/location-redirection-utilities/index.cjs.map +0 -1
- package/dist/location-redirection-utilities/resolveWithLocationRedirection.cjs.map +0 -1
- package/dist/noopHeuristic.cjs.map +0 -1
- package/dist/packageVersion.cjs.map +0 -1
- package/dist/protocol.cjs.map +0 -1
- package/dist/protocolTreeDocumentStorageService.cjs.map +0 -1
- package/dist/quorum.cjs.map +0 -1
- package/dist/retriableDocumentStorageService.cjs.map +0 -1
- package/dist/utils.cjs +0 -142
- package/dist/utils.cjs.map +0 -1
- package/tsc-multi.test.json +0 -4
- /package/{.eslintrc.js → .eslintrc.cjs} +0 -0
package/lib/container.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"container.d.mts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAKI,EAEN,oBAAoB,EAEpB,QAAQ,EACR,
|
|
1
|
+
{"version":3,"file":"container.d.mts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA;;;GAGG;OAKI,EAEN,oBAAoB,EAEpB,WAAW,EAEX,QAAQ,EACR,MAAM,iCAAiC;OACjC,EACN,WAAW,EAEX,SAAS,EAET,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EAOjB,YAAY,EAGZ,MAAM,uCAAuC;OACvC,EAEN,uBAAuB,EAEvB,YAAY,EAGZ,YAAY,EACZ,MAAM,oCAAoC;OAWpC,EAEN,cAAc,EAGd,gBAAgB,EAChB,cAAc,EAGd,yBAAyB,EAGzB,aAAa,EAMb,MAAM,sCAAsC;OACtC,EAEN,6BAA6B,EAQ7B,mBAAmB,EAKnB,MAAM,iCAAiC;OAYjC,EAAE,oBAAoB,EAAE,cAAc,EAAkB;OAExD,EAGN,yBAAyB,EACzB;OAcM,EAAE,eAAe,EAAE;OACnB,EAGN,sBAAsB,EAEtB;AAUD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IACnC;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC;IACnC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC;;OAEG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAEvC;;OAEG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;IAEpD;;OAEG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACrC;;OAEG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC;;OAEG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,cAAc,CAAC;IAEhD;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;IACzD;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAEjC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAE5B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAEpD;;;OAGG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACzD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,UAAU,oBA0EjE;AAMD;;;;;GAKG;AACH,wBAAsB,eAAe,CACpC,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,iBAO3C;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC,mBAAmB,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,YAAY,EAAE,aAAa,CAAC;IAC5B;;;OAGG;IACH,aAAa,EAAE,yBAAyB,CAAC;IACzC;;;;OAIG;IACH,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,aAAa,CAAC;IAC5B,aAAa,EAAE,yBAAyB,CAAC;IACzC,kBAAkB,EAAE,OAAO,CAAC;CAC5B;AASD,qBAAa,SACZ,SAAQ,6BAA6B,CAAC,gBAAgB,CACtD,YAAW,UAAU,EAAE,sBAAsB;IAE7C;;;OAGG;WACiB,IAAI,CACvB,SAAS,EAAE,mBAAmB,EAC9B,WAAW,EAAE,qBAAqB,GAChC,OAAO,CAAC,SAAS,CAAC;IA2DrB;;OAEG;WACiB,cAAc,CACjC,WAAW,EAAE,qBAAqB,EAClC,WAAW,EAAE,iBAAiB,GAC5B,OAAO,CAAC,SAAS,CAAC;IAcrB;;;OAGG;WACiB,6BAA6B,CAChD,WAAW,EAAE,qBAAqB,EAClC,QAAQ,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC;IAkBrB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA6B;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAe;IAC3C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0B;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAmC;IACvE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAyB;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IAEjC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC;;;OAGG;IACH,SAAgB,KAAK,EAAE,CACtB,SAAS,EAAE,mBAAmB,EAC9B,oBAAoB,EAAE,OAAO,CAAC,qBAAqB,CAAC,KAChD,OAAO,CAAC,SAAS,CAAC,CAAC;IAExB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,eAAe,CAMG;IAE1B,OAAO,CAAC,SAAS;IAUjB,IAAW,MAAM,IAAI,OAAO,CAI3B;IAED,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0B;IAEzD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAChE,OAAO,CAAC,OAAO,CAA+B;IAE9C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,KAAK,OAAO,GAKlB;IACD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,KAAK,eAAe,GAK1B;IAED,gHAAgH;IAChH,OAAO,CAAC,0BAA0B,CAAQ;IAC1C,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAgB;IAC1D,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,cAAc,CAAmD;IACzE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAA2B;IAClE,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAA0B;IACjE,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAqB;IAC9D,OAAO,CAAC,kBAAkB,CAAwC;IAElE,OAAO,CAAC,oBAAoB,CAAqB;IAEjD,OAAO,CAAC,aAAa,CAA4B;IAEjD,OAAO,KAAK,cAAc,GAEzB;IAED,IAAW,WAAW,IAAI,YAAY,GAAG,SAAS,CAajD;IAED,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED,IAAW,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAErD;IAED;;;;;;;;;;;;;;;;OAgBG;IACI,aAAa,CAAC,QAAQ,EAAE,OAAO;IAItC,IAAW,YAAY,IAAI,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CAEpF;IAED,IAAW,eAAe,IAAI,eAAe,CAE5C;IAED,OAAO,KAAK,SAAS,GAEpB;IAED,OAAO,CAAC,SAAS,CAAqB;IAEtC;;;OAGG;IACH,IAAW,QAAQ,IAAI,MAAM,GAAG,SAAS,CAExC;IAED,OAAO,KAAK,kBAAkB,GAM7B;IAED;;;OAGG;IACI,uBAAuB,IAAI,iBAAiB,GAAG,SAAS;IAI/D,OAAO,CAAC,kBAAkB,CAAgC;IAC1D;;;;OAIG;IACI,oBAAoB,IAAI,iBAAiB,GAAG,SAAS;IAI5D,OAAO,CAAC,aAAa,CAAsC;IAE3D;;OAEG;IACH,IAAW,QAAQ,IAAI,SAAS,CAE/B;IAED;;;;OAIG;IACH,IAAW,OAAO,YAEjB;IAED;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,WAAW,CAAC;IAyBlD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsD;IAEvF;;OAEG;gBAEF,WAAW,EAAE,qBAAqB,EAClC,SAAS,CAAC,EAAE,IAAI,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IA2O3D;;OAEG;IACI,SAAS,IAAI,cAAc;IAI3B,OAAO,CAAC,KAAK,CAAC,EAAE,uBAAuB;IAKvC,KAAK,CAAC,KAAK,CAAC,EAAE,uBAAuB;IAS5C,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,SAAS;IAkDjB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW;IAuDN,4BAA4B,CACxC,uBAAuB,CAAC,EAAE,WAAW,GACnC,OAAO,CAAC,MAAM,CAAC;IAYL,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;YAItC,wBAAwB;IA6CtC,IAAW,WAAW,IAAI,WAAW,CAEpC;IAEM,SAAS,IAAI,MAAM;IAsB1B,SAAgB,MAAM;;oCA6HpB;IAEF,OAAO,CAAC,wBAAwB;IAsBzB,OAAO;IAgBd,OAAO,CAAC,eAAe;IAehB,UAAU;IAQjB,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,cAAc;IActB,SAAgB,cAAc,gBAAuB,MAAM,KAAG,QAAQ,MAAM,GAAG,SAAS,CAAC,CAUvF;IAEW,kBAAkB,CAAC,WAAW,EAAE,iBAAiB;YAqBhD,mBAAmB;IAmBjC;;OAEG;YACW,SAAS;YAsCT,UAAU;IAKxB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAGpC;YAEY,qBAAqB;IAWnC;;;;OAIG;YACW,IAAI;YAoQJ,cAAc;YAwBd,6BAA6B;YA2C7B,qBAAqB;YAsBrB,mCAAmC;IAiCjD,OAAO,CAAC,uBAAuB;IA+C/B,OAAO,CAAC,sBAAsB;IA2B9B,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,MAAM,CAAC,WAAW;IAsC1B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,kBAAkB;YAwEZ,2BAA2B;IAiBzC,OAAO,CAAC,iCAAiC;IAkEzC,OAAO,CAAC,wBAAwB;IAwBhC,OAAO,CAAC,sBAAsB;IAuB9B,+DAA+D;IAC/D,OAAO,CAAC,WAAW;IAgBnB,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,oBAAoB;IAkD5B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IAUrB;;;;OAIG;YACW,iBAAiB;YAqBjB,aAAa;YA4Bb,kBAAkB;IAmFhC,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAMxC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAYhC,OAAO,CAAC,wBAAwB;CA2BhC;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,UAAU;IACzD;;;;;OAKG;IACH,oBAAoB,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzC;;;OAGG;IACH,4BAA4B,CAAC,CAAC,uBAAuB,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtF"}
|
package/lib/container.mjs
CHANGED
|
@@ -7,28 +7,29 @@ import { assert, unreachableCase } from "@fluidframework/core-utils";
|
|
|
7
7
|
import { TypedEventEmitter, performance } from "@fluid-internal/client-utils";
|
|
8
8
|
import { LogLevel, } from "@fluidframework/core-interfaces";
|
|
9
9
|
import { AttachState, isFluidCodeDetails, } from "@fluidframework/container-definitions";
|
|
10
|
-
import { readAndParse, OnlineStatus, isOnline,
|
|
10
|
+
import { readAndParse, OnlineStatus, isOnline, isCombinedAppAndProtocolSummary, MessageType2, isInstanceOfISnapshot, runWithRetry, } from "@fluidframework/driver-utils";
|
|
11
11
|
import { MessageType, SummaryType, } from "@fluidframework/protocol-definitions";
|
|
12
12
|
import { createChildLogger, EventEmitterWithErrorHandling, PerformanceEvent, raiseConnectedEvent, connectedEventName, normalizeError, createChildMonitoringContext, wrapError, formatTick, GenericError, UsageError, } from "@fluidframework/telemetry-utils";
|
|
13
|
+
import structuredClone from "@ungap/structured-clone";
|
|
13
14
|
import { Audience } from "./audience.mjs";
|
|
14
15
|
import { ContainerContext } from "./containerContext.mjs";
|
|
15
16
|
import { ReconnectMode, getPackageName, } from "./contracts.mjs";
|
|
16
17
|
import { DeltaManager } from "./deltaManager.mjs";
|
|
17
18
|
import { RelativeLoader } from "./loader.mjs";
|
|
18
19
|
import { pkgVersion } from "./packageVersion.mjs";
|
|
19
|
-
import { ContainerStorageAdapter, getBlobContentsFromTree,
|
|
20
|
+
import { ContainerStorageAdapter, getBlobContentsFromTree, } from "./containerStorageAdapter.mjs";
|
|
20
21
|
import { createConnectionStateHandler } from "./connectionStateHandler.mjs";
|
|
21
|
-
import { combineAppAndProtocolSummary, getProtocolSnapshotTree,
|
|
22
|
+
import { combineAppAndProtocolSummary, getProtocolSnapshotTree, getSnapshotTreeAndBlobsFromSerializedContainer, combineSnapshotTreeAndSnapshotBlobs, getDetachedContainerStateFromSerializedContainer, runSingle, } from "./utils.mjs";
|
|
22
23
|
import { initQuorumValuesFromCodeDetails } from "./quorum.mjs";
|
|
23
24
|
import { NoopHeuristic } from "./noopHeuristic.mjs";
|
|
24
25
|
import { ConnectionManager } from "./connectionManager.mjs";
|
|
25
26
|
import { ConnectionState } from "./connectionState.mjs";
|
|
26
27
|
import { ProtocolHandler, protocolHandlerShouldProcessSignal, } from "./protocol.mjs";
|
|
28
|
+
import { runRetriableAttachProcess } from "./attachment.mjs";
|
|
27
29
|
const detachedContainerRefSeqNumber = 0;
|
|
28
30
|
const dirtyContainerEvent = "dirty";
|
|
29
31
|
const savedContainerEvent = "saved";
|
|
30
32
|
const packageNotFactoryError = "Code package does not implement IRuntimeFactory";
|
|
31
|
-
const hasBlobsSummaryTree = ".hasAttachmentBlobs";
|
|
32
33
|
/**
|
|
33
34
|
* Waits until container connects to delta storage and gets up-to-date.
|
|
34
35
|
*
|
|
@@ -180,11 +181,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
180
181
|
static async rehydrateDetachedFromSnapshot(createProps, snapshot) {
|
|
181
182
|
const container = new Container(createProps);
|
|
182
183
|
return PerformanceEvent.timedExecAsync(container.mc.logger, { eventName: "RehydrateDetachedFromSnapshot" }, async (_event) => {
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
throw new UsageError("Cannot rehydrate detached container. Incorrect format");
|
|
186
|
-
}
|
|
187
|
-
await container.rehydrateDetachedFromSnapshot(deserializedSummary);
|
|
184
|
+
const detachedContainerState = getDetachedContainerStateFromSerializedContainer(snapshot);
|
|
185
|
+
await container.rehydrateDetachedFromSnapshot(detachedContainerState);
|
|
188
186
|
return container;
|
|
189
187
|
}, { start: true, end: true, cancel: "generic" });
|
|
190
188
|
}
|
|
@@ -235,6 +233,9 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
235
233
|
get readOnlyInfo() {
|
|
236
234
|
return this._deltaManager.readOnlyInfo;
|
|
237
235
|
}
|
|
236
|
+
get containerMetadata() {
|
|
237
|
+
return this._containerMetadata;
|
|
238
|
+
}
|
|
238
239
|
/**
|
|
239
240
|
* Sends signal to runtime (and data stores) to be read-only.
|
|
240
241
|
* Hosts may have read only views, indicating to data stores that no edits are allowed.
|
|
@@ -356,24 +357,103 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
356
357
|
* disposed: Container has been disposed
|
|
357
358
|
*/
|
|
358
359
|
this._lifecycleState = "loading";
|
|
359
|
-
this._attachState = AttachState.Detached;
|
|
360
360
|
/** During initialization we pause the inbound queues. We track this state to ensure we only call resume once */
|
|
361
361
|
this.inboundQueuePausedFromInit = true;
|
|
362
362
|
this.firstConnection = true;
|
|
363
363
|
this.connectionTransitionTimes = [];
|
|
364
|
-
this.attachStarted = false;
|
|
365
364
|
this._dirtyContainer = false;
|
|
366
365
|
this.savedOps = [];
|
|
366
|
+
this.attachmentData = { state: AttachState.Detached };
|
|
367
367
|
this.clientsWhoShouldHaveLeft = new Set();
|
|
368
|
+
this._containerMetadata = {};
|
|
368
369
|
this.setAutoReconnectTime = performance.now();
|
|
369
370
|
this._lifecycleEvents = new TypedEventEmitter();
|
|
370
371
|
this._disposed = false;
|
|
372
|
+
this.attach = runSingle(async (request, attachProps) => {
|
|
373
|
+
await PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
|
|
374
|
+
if (this._lifecycleState !== "loaded" ||
|
|
375
|
+
this.attachmentData.state === AttachState.Attached) {
|
|
376
|
+
// pre-0.58 error message: containerNotValidForAttach
|
|
377
|
+
throw new UsageError(`The Container is not in a valid state for attach [${this._lifecycleState}] and [${this.attachState}]`);
|
|
378
|
+
}
|
|
379
|
+
const normalizeErrorAndClose = (error) => {
|
|
380
|
+
const newError = normalizeError(error);
|
|
381
|
+
this.close(newError);
|
|
382
|
+
// add resolved URL on error object so that host has the ability to find this document and delete it
|
|
383
|
+
newError.addTelemetryProperties({
|
|
384
|
+
resolvedUrl: this.service?.resolvedUrl?.url,
|
|
385
|
+
});
|
|
386
|
+
return newError;
|
|
387
|
+
};
|
|
388
|
+
const setAttachmentData = (attachmentData) => {
|
|
389
|
+
const previousState = this.attachmentData.state;
|
|
390
|
+
this.attachmentData = attachmentData;
|
|
391
|
+
const state = this.attachmentData.state;
|
|
392
|
+
if (state !== previousState && state !== AttachState.Detached) {
|
|
393
|
+
try {
|
|
394
|
+
this.runtime.setAttachState(state);
|
|
395
|
+
this.emit(state.toLocaleLowerCase());
|
|
396
|
+
}
|
|
397
|
+
catch (error) {
|
|
398
|
+
throw normalizeErrorAndClose(error);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
const createAttachmentSummary = (redirectTable) => {
|
|
403
|
+
try {
|
|
404
|
+
assert(this.deltaManager.inbound.length === 0, 0x0d6 /* "Inbound queue should be empty when attaching" */);
|
|
405
|
+
return combineAppAndProtocolSummary(this.runtime.createSummary(redirectTable), this.captureProtocolSummary());
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
throw normalizeErrorAndClose(error);
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
const createOrGetStorageService = async (summary) => {
|
|
412
|
+
// Actually go and create the resolved document
|
|
413
|
+
if (this.service === undefined) {
|
|
414
|
+
const createNewResolvedUrl = await this.urlResolver.resolve(request);
|
|
415
|
+
assert(this.client.details.type !== summarizerClientType &&
|
|
416
|
+
createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
417
|
+
this.service = await runWithRetry(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
418
|
+
cancel: this._deltaManager.closeAbortController.signal,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
this.storageAdapter.connectToService(this.service);
|
|
422
|
+
return this.storageAdapter;
|
|
423
|
+
};
|
|
424
|
+
let attachP = runRetriableAttachProcess({
|
|
425
|
+
initialAttachmentData: this.attachmentData,
|
|
426
|
+
offlineLoadEnabled: this.offlineLoadEnabled,
|
|
427
|
+
detachedBlobStorage: this.detachedBlobStorage,
|
|
428
|
+
setAttachmentData,
|
|
429
|
+
createAttachmentSummary,
|
|
430
|
+
createOrGetStorageService,
|
|
431
|
+
});
|
|
432
|
+
// only enable the new behavior if the config is set
|
|
433
|
+
if (this.mc.config.getBoolean("Fluid.Container.RetryOnAttachFailure") !== true) {
|
|
434
|
+
attachP = attachP.catch((error) => {
|
|
435
|
+
throw normalizeErrorAndClose(error);
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
await attachP;
|
|
439
|
+
if (!this.closed) {
|
|
440
|
+
this.handleDeltaConnectionArg({
|
|
441
|
+
fetchOpsFromStorage: false,
|
|
442
|
+
reason: { text: "createDetached" },
|
|
443
|
+
}, attachProps?.deltaConnection);
|
|
444
|
+
}
|
|
445
|
+
}, { start: true, end: true, cancel: "generic" });
|
|
446
|
+
});
|
|
371
447
|
this.getAbsoluteUrl = async (relativeUrl) => {
|
|
372
448
|
if (this.resolvedUrl === undefined) {
|
|
373
449
|
return undefined;
|
|
374
450
|
}
|
|
375
451
|
return this.urlResolver.getAbsoluteUrl(this.resolvedUrl, relativeUrl, getPackageName(this._loadedCodeDetails));
|
|
376
452
|
};
|
|
453
|
+
this.metadataUpdateHandler = (metadata) => {
|
|
454
|
+
this._containerMetadata = { ...this._containerMetadata, ...metadata };
|
|
455
|
+
this.emit("metadataUpdate", metadata);
|
|
456
|
+
};
|
|
377
457
|
this.updateDirtyContainerState = (dirty) => {
|
|
378
458
|
if (this._dirtyContainer === dirty) {
|
|
379
459
|
return;
|
|
@@ -421,7 +501,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
421
501
|
clientType,
|
|
422
502
|
containerId: this._containerId,
|
|
423
503
|
docId: () => this.resolvedUrl?.id,
|
|
424
|
-
containerAttachState: () => this.
|
|
504
|
+
containerAttachState: () => this.attachState,
|
|
425
505
|
containerLifecycleState: () => this._lifecycleState,
|
|
426
506
|
containerConnectionState: () => ConnectionState[this.connectionState],
|
|
427
507
|
serializedContainer: pendingLocalState !== undefined,
|
|
@@ -572,6 +652,10 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
572
652
|
: "generic",
|
|
573
653
|
}, error);
|
|
574
654
|
this._lifecycleState = "closing";
|
|
655
|
+
// Back-compat for Old driver
|
|
656
|
+
if (this.service?.off !== undefined) {
|
|
657
|
+
this.service?.off("metadataUpdate", this.metadataUpdateHandler);
|
|
658
|
+
}
|
|
575
659
|
this._protocolHandler?.close();
|
|
576
660
|
this.connectionStateHandler.dispose();
|
|
577
661
|
}
|
|
@@ -659,15 +743,14 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
659
743
|
if (this.closed || this._disposed) {
|
|
660
744
|
throw new UsageError("Pending state cannot be retried if the container is closed or disposed");
|
|
661
745
|
}
|
|
662
|
-
assert(this.
|
|
746
|
+
assert(this.attachmentData.state === AttachState.Attached, 0x0d1 /* "Container should be attached before close" */);
|
|
663
747
|
assert(this.resolvedUrl !== undefined && this.resolvedUrl.type === "fluid", 0x0d2 /* "resolved url should be valid Fluid url" */);
|
|
664
|
-
assert(
|
|
665
|
-
assert(!!this.baseSnapshotBlobs, 0x5d5 /* no snapshot blobs */);
|
|
748
|
+
assert(this.attachmentData.snapshot !== undefined, 0x5d5 /* no base data */);
|
|
666
749
|
const pendingRuntimeState = await this.runtime.getPendingLocalState(props);
|
|
667
750
|
const pendingState = {
|
|
668
751
|
pendingRuntimeState,
|
|
669
|
-
baseSnapshot: this.
|
|
670
|
-
snapshotBlobs: this.
|
|
752
|
+
baseSnapshot: this.attachmentData.snapshot.tree,
|
|
753
|
+
snapshotBlobs: this.attachmentData.snapshot.blobs,
|
|
671
754
|
savedOps: this.savedOps,
|
|
672
755
|
url: this.resolvedUrl.url,
|
|
673
756
|
// no need to save this if there is no pending runtime state
|
|
@@ -677,119 +760,21 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
677
760
|
});
|
|
678
761
|
}
|
|
679
762
|
get attachState() {
|
|
680
|
-
return this.
|
|
763
|
+
return this.attachmentData.state;
|
|
681
764
|
}
|
|
682
765
|
serialize() {
|
|
683
766
|
assert(this.attachState === AttachState.Detached, 0x0d3 /* "Should only be called in detached container" */);
|
|
684
767
|
const appSummary = this.runtime.createSummary();
|
|
685
768
|
const protocolSummary = this.captureProtocolSummary();
|
|
686
769
|
const combinedSummary = combineAppAndProtocolSummary(appSummary, protocolSummary);
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
async attach(request, attachProps) {
|
|
696
|
-
await PerformanceEvent.timedExecAsync(this.mc.logger, { eventName: "Attach" }, async () => {
|
|
697
|
-
if (this._lifecycleState !== "loaded") {
|
|
698
|
-
// pre-0.58 error message: containerNotValidForAttach
|
|
699
|
-
throw new UsageError(`The Container is not in a valid state for attach [${this._lifecycleState}]`);
|
|
700
|
-
}
|
|
701
|
-
// If container is already attached or attach is in progress, throw an error.
|
|
702
|
-
assert(this._attachState === AttachState.Detached && !this.attachStarted, 0x205 /* "attach() called more than once" */);
|
|
703
|
-
this.attachStarted = true;
|
|
704
|
-
// If attachment blobs were uploaded in detached state we will go through a different attach flow
|
|
705
|
-
const hasAttachmentBlobs = this.detachedBlobStorage !== undefined && this.detachedBlobStorage.size > 0;
|
|
706
|
-
try {
|
|
707
|
-
assert(this.deltaManager.inbound.length === 0, 0x0d6 /* "Inbound queue should be empty when attaching" */);
|
|
708
|
-
let summary;
|
|
709
|
-
if (!hasAttachmentBlobs) {
|
|
710
|
-
// Get the document state post attach - possibly can just call attach but we need to change the
|
|
711
|
-
// semantics around what the attach means as far as async code goes.
|
|
712
|
-
const appSummary = this.runtime.createSummary();
|
|
713
|
-
const protocolSummary = this.captureProtocolSummary();
|
|
714
|
-
summary = combineAppAndProtocolSummary(appSummary, protocolSummary);
|
|
715
|
-
// Set the state as attaching as we are starting the process of attaching container.
|
|
716
|
-
// This should be fired after taking the summary because it is the place where we are
|
|
717
|
-
// starting to attach the container to storage.
|
|
718
|
-
// Also, this should only be fired in detached container.
|
|
719
|
-
this._attachState = AttachState.Attaching;
|
|
720
|
-
this.runtime.setAttachState(AttachState.Attaching);
|
|
721
|
-
this.emit("attaching");
|
|
722
|
-
if (this.offlineLoadEnabled) {
|
|
723
|
-
const snapshot = getSnapshotTreeFromSerializedContainer(summary);
|
|
724
|
-
this.baseSnapshot = snapshot;
|
|
725
|
-
this.baseSnapshotBlobs =
|
|
726
|
-
getBlobContentsFromTreeWithBlobContents(snapshot);
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
// Actually go and create the resolved document
|
|
730
|
-
if (this.service === undefined) {
|
|
731
|
-
const createNewResolvedUrl = await this.urlResolver.resolve(request);
|
|
732
|
-
assert(this.client.details.type !== summarizerClientType &&
|
|
733
|
-
createNewResolvedUrl !== undefined, 0x2c4 /* "client should not be summarizer before container is created" */);
|
|
734
|
-
this.service = await runWithRetry(async () => this.serviceFactory.createContainer(summary, createNewResolvedUrl, this.subLogger, false), "containerAttach", this.mc.logger, {
|
|
735
|
-
cancel: this._deltaManager.closeAbortController.signal,
|
|
736
|
-
});
|
|
737
|
-
}
|
|
738
|
-
this.storageAdapter.connectToService(this.service);
|
|
739
|
-
if (hasAttachmentBlobs) {
|
|
740
|
-
// upload blobs to storage
|
|
741
|
-
assert(!!this.detachedBlobStorage, 0x24e /* "assertion for type narrowing" */);
|
|
742
|
-
// build a table mapping IDs assigned locally to IDs assigned by storage and pass it to runtime to
|
|
743
|
-
// support blob handles that only know about the local IDs
|
|
744
|
-
const redirectTable = new Map();
|
|
745
|
-
// if new blobs are added while uploading, upload them too
|
|
746
|
-
while (redirectTable.size < this.detachedBlobStorage.size) {
|
|
747
|
-
const newIds = this.detachedBlobStorage
|
|
748
|
-
.getBlobIds()
|
|
749
|
-
.filter((id) => !redirectTable.has(id));
|
|
750
|
-
for (const id of newIds) {
|
|
751
|
-
const blob = await this.detachedBlobStorage.readBlob(id);
|
|
752
|
-
const response = await this.storageAdapter.createBlob(blob);
|
|
753
|
-
redirectTable.set(id, response.id);
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
// take summary and upload
|
|
757
|
-
const appSummary = this.runtime.createSummary(redirectTable);
|
|
758
|
-
const protocolSummary = this.captureProtocolSummary();
|
|
759
|
-
summary = combineAppAndProtocolSummary(appSummary, protocolSummary);
|
|
760
|
-
this._attachState = AttachState.Attaching;
|
|
761
|
-
this.runtime.setAttachState(AttachState.Attaching);
|
|
762
|
-
this.emit("attaching");
|
|
763
|
-
if (this.offlineLoadEnabled) {
|
|
764
|
-
const snapshot = getSnapshotTreeFromSerializedContainer(summary);
|
|
765
|
-
this.baseSnapshot = snapshot;
|
|
766
|
-
this.baseSnapshotBlobs =
|
|
767
|
-
getBlobContentsFromTreeWithBlobContents(snapshot);
|
|
768
|
-
}
|
|
769
|
-
await this.storageAdapter.uploadSummaryWithContext(summary, {
|
|
770
|
-
referenceSequenceNumber: 0,
|
|
771
|
-
ackHandle: undefined,
|
|
772
|
-
proposalHandle: undefined,
|
|
773
|
-
});
|
|
774
|
-
}
|
|
775
|
-
this._attachState = AttachState.Attached;
|
|
776
|
-
this.runtime.setAttachState(AttachState.Attached);
|
|
777
|
-
this.emit("attached");
|
|
778
|
-
if (!this.closed) {
|
|
779
|
-
this.handleDeltaConnectionArg({
|
|
780
|
-
fetchOpsFromStorage: false,
|
|
781
|
-
reason: { text: "createDetached" },
|
|
782
|
-
}, attachProps?.deltaConnection);
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
catch (error) {
|
|
786
|
-
// add resolved URL on error object so that host has the ability to find this document and delete it
|
|
787
|
-
const newError = normalizeError(error);
|
|
788
|
-
newError.addTelemetryProperties({ resolvedUrl: this.resolvedUrl?.url });
|
|
789
|
-
this.close(newError);
|
|
790
|
-
throw newError;
|
|
791
|
-
}
|
|
792
|
-
}, { start: true, end: true, cancel: "generic" });
|
|
770
|
+
const { tree: snapshot, blobs } = getSnapshotTreeAndBlobsFromSerializedContainer(combinedSummary);
|
|
771
|
+
const detachedContainerState = {
|
|
772
|
+
attached: false,
|
|
773
|
+
baseSnapshot: snapshot,
|
|
774
|
+
snapshotBlobs: blobs,
|
|
775
|
+
hasAttachmentBlobs: !!this.detachedBlobStorage && this.detachedBlobStorage.size > 0,
|
|
776
|
+
};
|
|
777
|
+
return JSON.stringify(detachedContainerState);
|
|
793
778
|
}
|
|
794
779
|
setAutoReconnectInternal(mode, reason) {
|
|
795
780
|
const currentMode = this._deltaManager.connectionManager.reconnectMode;
|
|
@@ -811,7 +796,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
811
796
|
if (this.closed) {
|
|
812
797
|
throw new UsageError(`The Container is closed and cannot be connected`);
|
|
813
798
|
}
|
|
814
|
-
else if (this.
|
|
799
|
+
else if (this.attachState !== AttachState.Attached) {
|
|
815
800
|
throw new UsageError(`The Container is not attached and cannot be connected`);
|
|
816
801
|
}
|
|
817
802
|
else if (!this.connected) {
|
|
@@ -826,7 +811,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
826
811
|
}
|
|
827
812
|
connectInternal(args) {
|
|
828
813
|
assert(!this.closed, 0x2c5 /* "Attempting to connect() a closed Container" */);
|
|
829
|
-
assert(this.
|
|
814
|
+
assert(this.attachState === AttachState.Attached, 0x2c6 /* "Attempting to connect() a container that is not attached" */);
|
|
830
815
|
// Resume processing ops and connect to delta stream
|
|
831
816
|
this.resumeInternal(args);
|
|
832
817
|
// Set Auto Reconnect Mode
|
|
@@ -930,6 +915,14 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
930
915
|
}
|
|
931
916
|
this._deltaManager.connect(args);
|
|
932
917
|
}
|
|
918
|
+
async createDocumentService(serviceProvider) {
|
|
919
|
+
const service = await serviceProvider();
|
|
920
|
+
// Back-compat for Old driver
|
|
921
|
+
if (service.on !== undefined) {
|
|
922
|
+
service.on("metadataUpdate", this.metadataUpdateHandler);
|
|
923
|
+
}
|
|
924
|
+
return service;
|
|
925
|
+
}
|
|
933
926
|
/**
|
|
934
927
|
* Load container.
|
|
935
928
|
*
|
|
@@ -937,7 +930,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
937
930
|
*/
|
|
938
931
|
async load(specifiedVersion, loadMode, resolvedUrl, pendingLocalState, loadToSequenceNumber) {
|
|
939
932
|
const timings = { phase1: performance.now() };
|
|
940
|
-
this.service = await this.serviceFactory.createDocumentService(resolvedUrl, this.subLogger, this.client.details.type === summarizerClientType);
|
|
933
|
+
this.service = await this.createDocumentService(async () => this.serviceFactory.createDocumentService(resolvedUrl, this.subLogger, this.client.details.type === summarizerClientType));
|
|
941
934
|
// Except in cases where it has stashed ops or requested by feature gate, the container will connect in "read" mode
|
|
942
935
|
const mode = this.mc.config.getBoolean("Fluid.Container.ForceWriteConnection") === true ||
|
|
943
936
|
(pendingLocalState?.savedOps.length ?? 0) > 0
|
|
@@ -954,25 +947,37 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
954
947
|
this.connectToDeltaStream(connectionArgs);
|
|
955
948
|
}
|
|
956
949
|
this.storageAdapter.connectToService(this.service);
|
|
957
|
-
this.
|
|
950
|
+
this.attachmentData = {
|
|
951
|
+
state: AttachState.Attached,
|
|
952
|
+
};
|
|
958
953
|
timings.phase2 = performance.now();
|
|
959
954
|
// Fetch specified snapshot.
|
|
960
955
|
const { snapshot, versionId } = pendingLocalState === undefined
|
|
961
|
-
? await this.
|
|
956
|
+
? await this.fetchSnapshot(specifiedVersion)
|
|
962
957
|
: { snapshot: pendingLocalState.baseSnapshot, versionId: undefined };
|
|
958
|
+
const snapshotTree = isInstanceOfISnapshot(snapshot)
|
|
959
|
+
? snapshot.snapshotTree
|
|
960
|
+
: snapshot;
|
|
963
961
|
if (pendingLocalState) {
|
|
964
|
-
this.
|
|
965
|
-
|
|
962
|
+
this.attachmentData = {
|
|
963
|
+
state: AttachState.Attached,
|
|
964
|
+
snapshot: {
|
|
965
|
+
tree: pendingLocalState.baseSnapshot,
|
|
966
|
+
blobs: pendingLocalState.snapshotBlobs,
|
|
967
|
+
},
|
|
968
|
+
};
|
|
966
969
|
}
|
|
967
970
|
else {
|
|
968
|
-
assert(
|
|
971
|
+
assert(snapshotTree !== undefined, 0x237 /* "Snapshot should exist" */);
|
|
969
972
|
if (this.offlineLoadEnabled) {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
+
const blobs = await getBlobContentsFromTree(snapshotTree, this.storageAdapter);
|
|
974
|
+
this.attachmentData = {
|
|
975
|
+
state: AttachState.Attached,
|
|
976
|
+
snapshot: { tree: snapshotTree, blobs },
|
|
977
|
+
};
|
|
973
978
|
}
|
|
974
979
|
}
|
|
975
|
-
const attributes = await this.getDocumentAttributes(this.storageAdapter,
|
|
980
|
+
const attributes = await this.getDocumentAttributes(this.storageAdapter, snapshotTree);
|
|
976
981
|
// If we saved ops, we will replay them and don't need DeltaManager to fetch them
|
|
977
982
|
const sequenceNumber = pendingLocalState?.savedOps[pendingLocalState.savedOps.length - 1]?.sequenceNumber;
|
|
978
983
|
const dmAttributes = sequenceNumber !== undefined ? { ...attributes, sequenceNumber } : attributes;
|
|
@@ -1037,12 +1042,12 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1037
1042
|
}
|
|
1038
1043
|
// ...load in the existing quorum
|
|
1039
1044
|
// Initialize the protocol handler
|
|
1040
|
-
await this.initializeProtocolStateFromSnapshot(attributes, this.storageAdapter,
|
|
1045
|
+
await this.initializeProtocolStateFromSnapshot(attributes, this.storageAdapter, snapshotTree);
|
|
1041
1046
|
timings.phase3 = performance.now();
|
|
1042
1047
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
1043
|
-
await this.instantiateRuntime(codeDetails,
|
|
1048
|
+
await this.instantiateRuntime(codeDetails, snapshotTree,
|
|
1044
1049
|
// give runtime a dummy value so it knows we're loading from a stash blob
|
|
1045
|
-
pendingLocalState ? pendingLocalState?.pendingRuntimeState ?? {} : undefined);
|
|
1050
|
+
pendingLocalState ? pendingLocalState?.pendingRuntimeState ?? {} : undefined, isInstanceOfISnapshot(snapshot) ? snapshot : undefined);
|
|
1046
1051
|
// replay saved ops
|
|
1047
1052
|
if (pendingLocalState) {
|
|
1048
1053
|
for (const message of pendingLocalState.savedOps) {
|
|
@@ -1118,18 +1123,16 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1118
1123
|
await this.instantiateRuntime(codeDetails, undefined);
|
|
1119
1124
|
this.setLoaded();
|
|
1120
1125
|
}
|
|
1121
|
-
async rehydrateDetachedFromSnapshot(
|
|
1122
|
-
if (
|
|
1126
|
+
async rehydrateDetachedFromSnapshot({ attached, baseSnapshot, snapshotBlobs, hasAttachmentBlobs, }) {
|
|
1127
|
+
if (hasAttachmentBlobs) {
|
|
1123
1128
|
assert(!!this.detachedBlobStorage && this.detachedBlobStorage.size > 0, 0x250 /* "serialized container with attachment blobs must be rehydrated with detached blob storage" */);
|
|
1124
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
1125
|
-
delete detachedContainerSnapshot.tree[hasBlobsSummaryTree];
|
|
1126
1129
|
}
|
|
1127
|
-
const
|
|
1128
|
-
this.storageAdapter.
|
|
1129
|
-
const attributes = await this.getDocumentAttributes(this.storageAdapter,
|
|
1130
|
+
const snapshotTreeWithBlobContents = combineSnapshotTreeAndSnapshotBlobs(baseSnapshot, snapshotBlobs);
|
|
1131
|
+
this.storageAdapter.loadSnapshotFromSnapshotBlobs(snapshotBlobs);
|
|
1132
|
+
const attributes = await this.getDocumentAttributes(this.storageAdapter, snapshotTreeWithBlobContents);
|
|
1130
1133
|
await this.attachDeltaManagerOpHandler(attributes);
|
|
1131
1134
|
// Initialize the protocol handler
|
|
1132
|
-
const baseTree = getProtocolSnapshotTree(
|
|
1135
|
+
const baseTree = getProtocolSnapshotTree(snapshotTreeWithBlobContents);
|
|
1133
1136
|
const qValues = await readAndParse(this.storageAdapter, baseTree.blobs.quorumValues);
|
|
1134
1137
|
this.initializeProtocolState(attributes, {
|
|
1135
1138
|
members: [],
|
|
@@ -1137,7 +1140,7 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1137
1140
|
values: qValues,
|
|
1138
1141
|
});
|
|
1139
1142
|
const codeDetails = this.getCodeDetailsFromQuorum();
|
|
1140
|
-
await this.instantiateRuntime(codeDetails,
|
|
1143
|
+
await this.instantiateRuntime(codeDetails, snapshotTreeWithBlobContents);
|
|
1141
1144
|
this.setLoaded();
|
|
1142
1145
|
}
|
|
1143
1146
|
async getDocumentAttributes(storage, tree) {
|
|
@@ -1511,7 +1514,29 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1511
1514
|
}
|
|
1512
1515
|
return { snapshot, versionId: version?.id };
|
|
1513
1516
|
}
|
|
1514
|
-
async
|
|
1517
|
+
async fetchSnapshot(specifiedVersion) {
|
|
1518
|
+
if (this.mc.config.getBoolean("Fluid.Container.FetchSnapshotUsingGetSnapshotApi") ===
|
|
1519
|
+
true &&
|
|
1520
|
+
this.service?.policies?.supportGetSnapshotApi === true) {
|
|
1521
|
+
const snapshot = await this.storageAdapter.getSnapshot({
|
|
1522
|
+
versionId: specifiedVersion,
|
|
1523
|
+
});
|
|
1524
|
+
const version = {
|
|
1525
|
+
id: snapshot.snapshotTree.id ?? "",
|
|
1526
|
+
treeId: snapshot.snapshotTree.id ?? "",
|
|
1527
|
+
};
|
|
1528
|
+
this._loadedFromVersion = version;
|
|
1529
|
+
if (snapshot === undefined && specifiedVersion !== undefined) {
|
|
1530
|
+
this.mc.logger.sendErrorEvent({
|
|
1531
|
+
eventName: "getSnapshotTreeFailed",
|
|
1532
|
+
id: version.id,
|
|
1533
|
+
});
|
|
1534
|
+
}
|
|
1535
|
+
return { snapshot, versionId: version.id };
|
|
1536
|
+
}
|
|
1537
|
+
return this.fetchSnapshotTree(specifiedVersion);
|
|
1538
|
+
}
|
|
1539
|
+
async instantiateRuntime(codeDetails, snapshotTree, pendingLocalState, snapshot) {
|
|
1515
1540
|
assert(this._runtime?.disposed !== false, 0x0dd /* "Existing runtime not disposed" */);
|
|
1516
1541
|
// The relative loader will proxy requests to '/' to the loader itself assuming no non-cache flags
|
|
1517
1542
|
// are set. Global requests will still go directly to the loader
|
|
@@ -1532,8 +1557,8 @@ export class Container extends EventEmitterWithErrorHandling {
|
|
|
1532
1557
|
}
|
|
1533
1558
|
const getSpecifiedCodeDetails = () => (this.protocolHandler.quorum.get("code") ??
|
|
1534
1559
|
this.protocolHandler.quorum.get("code2"));
|
|
1535
|
-
const existing =
|
|
1536
|
-
const context = new ContainerContext(this.options, this.scope,
|
|
1560
|
+
const existing = snapshotTree !== undefined;
|
|
1561
|
+
const context = new ContainerContext(this.options, this.scope, snapshotTree, this._loadedFromVersion, this._deltaManager, this.storageAdapter, this.protocolHandler.quorum, this.protocolHandler.audience, loader, (type, contents, batch, metadata) => this.submitContainerMessage(type, contents, batch, metadata), (summaryOp, referenceSequenceNumber) => this.submitSummaryMessage(summaryOp, referenceSequenceNumber), (batch, referenceSequenceNumber) => this.submitBatch(batch, referenceSequenceNumber), (content, targetClientId) => this.submitSignal(content, targetClientId), (error) => this.dispose(error), (error) => this.close(error), this.updateDirtyContainerState, this.getAbsoluteUrl, () => this.resolvedUrl?.id, () => this.clientId, () => this.attachState, () => this.connected, getSpecifiedCodeDetails, this._deltaManager.clientDetails, existing, this.subLogger, pendingLocalState, snapshot);
|
|
1537
1562
|
this._runtime = await PerformanceEvent.timedExecAsync(this.subLogger, { eventName: "InstantiateRuntime" }, async () => runtimeFactory.instantiateRuntime(context, existing));
|
|
1538
1563
|
this._lifecycleEvents.emit("runtimeInstantiated");
|
|
1539
1564
|
this._loadedCodeDetails = codeDetails;
|