@fluidframework/container-loader 2.0.2 → 2.1.0-276326

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/.eslintrc.cjs +2 -5
  2. package/api-extractor/api-extractor.legacy.json +4 -0
  3. package/api-report/container-loader.beta.api.md +0 -27
  4. package/api-report/{container-loader.alpha.api.md → container-loader.legacy.alpha.api.md} +0 -27
  5. package/api-report/container-loader.public.api.md +0 -27
  6. package/dist/attachment.d.ts +2 -1
  7. package/dist/attachment.d.ts.map +1 -1
  8. package/dist/attachment.js.map +1 -1
  9. package/dist/audience.d.ts.map +1 -1
  10. package/dist/audience.js +4 -4
  11. package/dist/audience.js.map +1 -1
  12. package/dist/catchUpMonitor.d.ts +15 -4
  13. package/dist/catchUpMonitor.d.ts.map +1 -1
  14. package/dist/catchUpMonitor.js +12 -3
  15. package/dist/catchUpMonitor.js.map +1 -1
  16. package/dist/connectionManager.d.ts +24 -8
  17. package/dist/connectionManager.d.ts.map +1 -1
  18. package/dist/connectionManager.js +36 -23
  19. package/dist/connectionManager.js.map +1 -1
  20. package/dist/connectionStateHandler.d.ts +30 -20
  21. package/dist/connectionStateHandler.d.ts.map +1 -1
  22. package/dist/connectionStateHandler.js +15 -11
  23. package/dist/connectionStateHandler.js.map +1 -1
  24. package/dist/container.d.ts +7 -2
  25. package/dist/container.d.ts.map +1 -1
  26. package/dist/container.js +45 -28
  27. package/dist/container.js.map +1 -1
  28. package/dist/containerContext.d.ts +8 -4
  29. package/dist/containerContext.d.ts.map +1 -1
  30. package/dist/containerContext.js +3 -1
  31. package/dist/containerContext.js.map +1 -1
  32. package/dist/containerStorageAdapter.d.ts +1 -1
  33. package/dist/containerStorageAdapter.d.ts.map +1 -1
  34. package/dist/containerStorageAdapter.js +12 -6
  35. package/dist/containerStorageAdapter.js.map +1 -1
  36. package/dist/contracts.d.ts +17 -8
  37. package/dist/contracts.d.ts.map +1 -1
  38. package/dist/contracts.js +4 -2
  39. package/dist/contracts.js.map +1 -1
  40. package/dist/debugLogger.js +3 -3
  41. package/dist/debugLogger.js.map +1 -1
  42. package/dist/deltaManager.d.ts +13 -9
  43. package/dist/deltaManager.d.ts.map +1 -1
  44. package/dist/deltaManager.js +32 -23
  45. package/dist/deltaManager.js.map +1 -1
  46. package/dist/deltaQueue.d.ts +1 -4
  47. package/dist/deltaQueue.d.ts.map +1 -1
  48. package/dist/deltaQueue.js +2 -2
  49. package/dist/deltaQueue.js.map +1 -1
  50. package/dist/disposal.d.ts +1 -1
  51. package/dist/disposal.d.ts.map +1 -1
  52. package/dist/disposal.js.map +1 -1
  53. package/dist/error.d.ts.map +1 -1
  54. package/dist/error.js.map +1 -1
  55. package/dist/legacy.d.ts +1 -1
  56. package/dist/loadPaused.d.ts +2 -2
  57. package/dist/loadPaused.d.ts.map +1 -1
  58. package/dist/loadPaused.js +7 -3
  59. package/dist/loadPaused.js.map +1 -1
  60. package/dist/loader.d.ts +10 -1
  61. package/dist/loader.d.ts.map +1 -1
  62. package/dist/loader.js +11 -1
  63. package/dist/loader.js.map +1 -1
  64. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
  65. package/dist/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  66. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
  67. package/dist/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  68. package/dist/memoryBlobStorage.d.ts.map +1 -1
  69. package/dist/memoryBlobStorage.js +4 -2
  70. package/dist/memoryBlobStorage.js.map +1 -1
  71. package/dist/noopHeuristic.js +1 -1
  72. package/dist/noopHeuristic.js.map +1 -1
  73. package/dist/packageVersion.d.ts +1 -1
  74. package/dist/packageVersion.d.ts.map +1 -1
  75. package/dist/packageVersion.js +1 -1
  76. package/dist/packageVersion.js.map +1 -1
  77. package/dist/protocol/protocol.d.ts +4 -3
  78. package/dist/protocol/protocol.d.ts.map +1 -1
  79. package/dist/protocol/protocol.js +6 -5
  80. package/dist/protocol/protocol.js.map +1 -1
  81. package/dist/protocol/quorum.d.ts +11 -8
  82. package/dist/protocol/quorum.d.ts.map +1 -1
  83. package/dist/protocol/quorum.js +8 -8
  84. package/dist/protocol/quorum.js.map +1 -1
  85. package/dist/protocol.d.ts +2 -0
  86. package/dist/protocol.d.ts.map +1 -1
  87. package/dist/protocol.js +7 -2
  88. package/dist/protocol.js.map +1 -1
  89. package/dist/protocolTreeDocumentStorageService.d.ts +2 -2
  90. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  91. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  92. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  93. package/dist/retriableDocumentStorageService.js +4 -1
  94. package/dist/retriableDocumentStorageService.js.map +1 -1
  95. package/dist/serializedStateManager.d.ts +29 -12
  96. package/dist/serializedStateManager.d.ts.map +1 -1
  97. package/dist/serializedStateManager.js +55 -24
  98. package/dist/serializedStateManager.js.map +1 -1
  99. package/dist/utils.d.ts +4 -2
  100. package/dist/utils.d.ts.map +1 -1
  101. package/dist/utils.js +15 -6
  102. package/dist/utils.js.map +1 -1
  103. package/lib/attachment.d.ts +2 -1
  104. package/lib/attachment.d.ts.map +1 -1
  105. package/lib/attachment.js.map +1 -1
  106. package/lib/audience.d.ts.map +1 -1
  107. package/lib/audience.js +4 -4
  108. package/lib/audience.js.map +1 -1
  109. package/lib/catchUpMonitor.d.ts +15 -4
  110. package/lib/catchUpMonitor.d.ts.map +1 -1
  111. package/lib/catchUpMonitor.js +12 -3
  112. package/lib/catchUpMonitor.js.map +1 -1
  113. package/lib/connectionManager.d.ts +24 -8
  114. package/lib/connectionManager.d.ts.map +1 -1
  115. package/lib/connectionManager.js +36 -23
  116. package/lib/connectionManager.js.map +1 -1
  117. package/lib/connectionStateHandler.d.ts +30 -20
  118. package/lib/connectionStateHandler.d.ts.map +1 -1
  119. package/lib/connectionStateHandler.js +14 -12
  120. package/lib/connectionStateHandler.js.map +1 -1
  121. package/lib/container.d.ts +7 -2
  122. package/lib/container.d.ts.map +1 -1
  123. package/lib/container.js +45 -28
  124. package/lib/container.js.map +1 -1
  125. package/lib/containerContext.d.ts +8 -4
  126. package/lib/containerContext.d.ts.map +1 -1
  127. package/lib/containerContext.js +3 -1
  128. package/lib/containerContext.js.map +1 -1
  129. package/lib/containerStorageAdapter.d.ts +1 -1
  130. package/lib/containerStorageAdapter.d.ts.map +1 -1
  131. package/lib/containerStorageAdapter.js +12 -6
  132. package/lib/containerStorageAdapter.js.map +1 -1
  133. package/lib/contracts.d.ts +17 -8
  134. package/lib/contracts.d.ts.map +1 -1
  135. package/lib/contracts.js +4 -2
  136. package/lib/contracts.js.map +1 -1
  137. package/lib/debugLogger.js +3 -3
  138. package/lib/debugLogger.js.map +1 -1
  139. package/lib/deltaManager.d.ts +13 -9
  140. package/lib/deltaManager.d.ts.map +1 -1
  141. package/lib/deltaManager.js +32 -23
  142. package/lib/deltaManager.js.map +1 -1
  143. package/lib/deltaQueue.d.ts +1 -4
  144. package/lib/deltaQueue.d.ts.map +1 -1
  145. package/lib/deltaQueue.js +2 -2
  146. package/lib/deltaQueue.js.map +1 -1
  147. package/lib/disposal.d.ts +1 -1
  148. package/lib/disposal.d.ts.map +1 -1
  149. package/lib/disposal.js.map +1 -1
  150. package/lib/error.d.ts.map +1 -1
  151. package/lib/error.js.map +1 -1
  152. package/lib/legacy.d.ts +1 -1
  153. package/lib/loadPaused.d.ts +2 -2
  154. package/lib/loadPaused.d.ts.map +1 -1
  155. package/lib/loadPaused.js +8 -4
  156. package/lib/loadPaused.js.map +1 -1
  157. package/lib/loader.d.ts +10 -1
  158. package/lib/loader.d.ts.map +1 -1
  159. package/lib/loader.js +11 -1
  160. package/lib/loader.js.map +1 -1
  161. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts +2 -1
  162. package/lib/location-redirection-utilities/resolveWithLocationRedirection.d.ts.map +1 -1
  163. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js +3 -1
  164. package/lib/location-redirection-utilities/resolveWithLocationRedirection.js.map +1 -1
  165. package/lib/memoryBlobStorage.d.ts.map +1 -1
  166. package/lib/memoryBlobStorage.js +4 -2
  167. package/lib/memoryBlobStorage.js.map +1 -1
  168. package/lib/noopHeuristic.js +1 -1
  169. package/lib/noopHeuristic.js.map +1 -1
  170. package/lib/packageVersion.d.ts +1 -1
  171. package/lib/packageVersion.d.ts.map +1 -1
  172. package/lib/packageVersion.js +1 -1
  173. package/lib/packageVersion.js.map +1 -1
  174. package/lib/protocol/protocol.d.ts +4 -3
  175. package/lib/protocol/protocol.d.ts.map +1 -1
  176. package/lib/protocol/protocol.js +6 -5
  177. package/lib/protocol/protocol.js.map +1 -1
  178. package/lib/protocol/quorum.d.ts +11 -8
  179. package/lib/protocol/quorum.d.ts.map +1 -1
  180. package/lib/protocol/quorum.js +8 -8
  181. package/lib/protocol/quorum.js.map +1 -1
  182. package/lib/protocol.d.ts +2 -0
  183. package/lib/protocol.d.ts.map +1 -1
  184. package/lib/protocol.js +7 -2
  185. package/lib/protocol.js.map +1 -1
  186. package/lib/protocolTreeDocumentStorageService.d.ts +2 -2
  187. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  188. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  189. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  190. package/lib/retriableDocumentStorageService.js +4 -1
  191. package/lib/retriableDocumentStorageService.js.map +1 -1
  192. package/lib/serializedStateManager.d.ts +29 -12
  193. package/lib/serializedStateManager.d.ts.map +1 -1
  194. package/lib/serializedStateManager.js +56 -25
  195. package/lib/serializedStateManager.js.map +1 -1
  196. package/lib/utils.d.ts +4 -2
  197. package/lib/utils.d.ts.map +1 -1
  198. package/lib/utils.js +16 -7
  199. package/lib/utils.js.map +1 -1
  200. package/package.json +21 -17
  201. package/src/attachment.ts +2 -1
  202. package/src/audience.ts +4 -4
  203. package/src/catchUpMonitor.ts +23 -8
  204. package/src/connectionManager.ts +85 -60
  205. package/src/connectionStateHandler.ts +85 -63
  206. package/src/container.ts +118 -84
  207. package/src/containerContext.ts +5 -3
  208. package/src/containerStorageAdapter.ts +20 -13
  209. package/src/contracts.ts +21 -9
  210. package/src/debugLogger.ts +4 -4
  211. package/src/deltaManager.ts +75 -56
  212. package/src/deltaQueue.ts +16 -10
  213. package/src/disposal.ts +3 -3
  214. package/src/error.ts +2 -1
  215. package/src/loadPaused.ts +16 -8
  216. package/src/loader.ts +20 -2
  217. package/src/location-redirection-utilities/resolveWithLocationRedirection.ts +7 -3
  218. package/src/memoryBlobStorage.ts +5 -3
  219. package/src/noopHeuristic.ts +1 -1
  220. package/src/packageVersion.ts +1 -1
  221. package/src/protocol/protocol.ts +12 -11
  222. package/src/protocol/quorum.ts +49 -40
  223. package/src/protocol.ts +12 -4
  224. package/src/protocolTreeDocumentStorageService.ts +3 -2
  225. package/src/retriableDocumentStorageService.ts +6 -3
  226. package/src/serializedStateManager.ts +95 -39
  227. package/src/utils.ts +26 -10
@@ -1 +1 @@
1
- {"version":3,"file":"connectionStateHandler.js","sourceRoot":"","sources":["../src/connectionStateHandler.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAIH,kEAAoE;AAGpE,uEAKkD;AAElD,2DAAsE;AACtE,6DAAuD;AAIvD,qGAAqG;AACrG,kGAAkG;AAClG,iEAAiE;AACjE,MAAM,eAAe,GAAG,KAAK,CAAC;AAE9B,2DAA2D;AAC3D,MAAM,mBAAmB,GAAG,KAAK,CAAC;AA8DlC,SAAgB,4BAA4B,CAC3C,MAAqC,EACrC,YAAqC,EACrC,QAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC;IAChC,OAAO,gCAAgC,CACtC,MAAM,CAAC,UAAU,CAAC,wDAAwD,CAAC,KAAK,IAAI,EAAE,8BAA8B;IACpH,MAAM,CAAC,UAAU,CAAC,uCAAuC,CAAC,KAAK,IAAI,EAAE,+BAA+B;IACpG,MAAM,EACN,YAAY,EACZ,QAAQ,CACR,CAAC;AACH,CAAC;AAbD,oEAaC;AAED,SAAgB,gCAAgC,CAC/C,2BAAoC,EACpC,4BAAqC,EACrC,MAAqC,EACrC,YAAqC,EACrC,QAAiB;IAEjB,MAAM,OAAO,GAAG,CAAC,OAAsC,EAAE,EAAE,CAC1D,IAAI,sBAAsB,CAAC,OAAO,EAAE,4BAA4B,EAAE,QAAQ,CAAC,CAAC;IAE7E,OAAO,2BAA2B;QACjC,CAAC,CAAC,IAAI,sBAAsB,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC;QAC3D,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACpB,CAAC;AAbD,4EAaC;AAaD;;;GAGG;AACH,MAAM,iCAAiC;IAKtC,YACoB,MAAqC,EACxD,YAAiF;QAD9D,WAAM,GAAN,MAAM,CAA+B;QAGxD,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;IACnC,CAAC;IACD,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;IACnC,CAAC;IACD,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAEM,cAAc;QACpB,OAAO,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;IACpC,CAAC;IACM,OAAO;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IACM,YAAY,CAAC,QAA0B;QAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACM,uBAAuB,CAAC,MAAqD;QACnF,OAAO,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAEM,sBAAsB,CAAC,MAAoC;QACjE,OAAO,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC;IAEM,4BAA4B,CAAC,MAAoC;QACvE,OAAO,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAEM,oBAAoB,CAAC,OAAmC;QAC9D,OAAO,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED;;OAEG;IAEH,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,IAAW,EAAE;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACvB,CAAC;IACM,sBAAsB,CAC5B,KAAsB,EACtB,QAAyB,EACzB,MAAqC;QAErC,OAAO,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpE,CAAC;IACM,qBAAqB;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,qBAAqB,EAAE,CAAC;IAC5C,CAAC;IACD,IAAW,sBAAsB;QAChC,OAAO,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC;IAC3C,CAAC;IACM,kBAAkB,CACxB,SAAiB,EACjB,QAAgC,EAChC,OAAkC;QAElC,OAAO,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IACM,oBAAoB,CAAC,QAAgB;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IACnD,CAAC;IAEM,eAAe,CAAC,KAAc;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,sBAAuB,SAAQ,iCAAiC;IAGrE,YACC,MAAqC,EACrC,YAAiF,EAChE,YAAqC;QAEtD,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QAFX,iBAAY,GAAZ,YAAY,CAAyB;QA0DtC,+BAA0B,GAAG,GAAG,EAAE;YAClD,kFAAkF;YAClF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;YACzC,IAAA,iBAAM,EAAC,KAAK,KAAK,oCAAe,CAAC,SAAS,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC1E,IAAA,iBAAM,EAAC,IAAI,CAAC,gBAAgB,KAAK,oCAAe,CAAC,UAAU,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC3F,IAAI,CAAC,gBAAgB,GAAG,oCAAe,CAAC,SAAS,CAAC;YAClD,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,oCAAe,CAAC,SAAS,EAAE,oCAAe,CAAC,UAAU,EAAE;gBACzF,IAAI,EAAE,WAAW;aACjB,CAAC,CAAC;QACJ,CAAC,CAAC;QAhED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC;IACpD,CAAC;IAGD,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;IAEM,sBAAsB,CAC5B,KAAsB,EACtB,QAAyB,EACzB,MAAsD;QAEtD,QAAQ,KAAK,EAAE,CAAC;YACf,KAAK,oCAAe,CAAC,SAAS;gBAC7B,IAAA,iBAAM,EACL,IAAI,CAAC,gBAAgB,KAAK,oCAAe,CAAC,UAAU,EACpD,KAAK,CAAC,8BAA8B,CACpC,CAAC;gBACF,mGAAmG;gBACnG,qGAAqG;gBACrG,oGAAoG;gBACpG,qGAAqG;gBACrG,qGAAqG;gBACrG,2CAA2C;gBAC3C,IAAA,iBAAM,EAAC,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBACrF,IAAI,CAAC,cAAc,GAAG,IAAI,kCAAc,CACvC,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,0BAA0B,CAC/B,CAAC;gBACF,OAAO;YACR,KAAK,oCAAe,CAAC,YAAY;gBAChC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;gBAC/B,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;gBAChC,MAAM;YACP,kGAAkG;YAClG,+DAA+D;YAC/D,KAAK,oCAAe,CAAC,sBAAsB;gBAC1C,IAAA,iBAAM,EACL,IAAI,CAAC,gBAAgB,KAAK,oCAAe,CAAC,YAAY,EACtD,KAAK,CAAC,wDAAwD,CAC9D,CAAC;gBACF,MAAM;YACP,KAAK,oCAAe,CAAC,UAAU;gBAC9B,IAAA,iBAAM,EACL,IAAI,CAAC,gBAAgB,KAAK,oCAAe,CAAC,sBAAsB,EAChE,KAAK,CAAC,8BAA8B,CACpC,CAAC;gBACF,MAAM;YACP,QAAQ;QACT,CAAC;QACD,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;CAYD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,sBAAsB;IAwB3B,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;IAED,IAAW,QAAQ;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC,gBAAgB,CAAC;IAC9B,CAAC;IAED,YACkB,OAAsC,EACtC,4BAAqC,EACtD,yBAAkC;QAFjB,YAAO,GAAP,OAAO,CAA+B;QACtC,iCAA4B,GAA5B,4BAA4B,CAAS;QArC/C,qBAAgB,GAAG,oCAAe,CAAC,YAAY,CAAC;QAwCvD,IAAI,CAAC,SAAS,GAAG,yBAAyB,CAAC;QAC3C,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;QACpE,IAAI,CAAC,mBAAmB,GAAG,IAAI,gBAAK;QACnC,+FAA+F;QAC/F,uDAAuD;QACvD,IAAI,CAAC,OAAO,CAAC,sBAAsB,IAAI,MAAM,EAC7C,GAAG,EAAE;YACJ,IAAA,iBAAM,EACL,IAAI,CAAC,eAAe,KAAK,oCAAe,CAAC,SAAS,EAClD,KAAK,CAAC,6EAA6E,CACnF,CAAC;YACF,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QACxC,CAAC,EACD,YAAY,CACZ,CAAC;QAEF,IAAI,CAAC,SAAS,GAAG,IAAI,gBAAK,CACzB,CAAC,EAAE,2EAA2E;QAC9E,GAAG,EAAE;YACJ,gFAAgF;YAChF,iGAAiG;YACjG,IAAI,IAAI,CAAC,eAAe,KAAK,oCAAe,CAAC,UAAU,EAAE,CAAC;gBACzD,OAAO;YACR,CAAC;YACD,MAAM,OAAO,GAAG;gBACf,mBAAmB,EAAE,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAChD,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC;gBAClD,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;aACzC,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAC9B,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,YAAY;YAC5E,OAAO,EAAE,WAAW;YACpB,OAAO,CACP,CAAC;QACH,CAAC,EACD,YAAY,CACZ,CAAC;IACH,CAAC;IAEO,cAAc;QACrB,IAAA,iBAAM,EAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAC9D,IAAA,iBAAM,EAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACnE,IAAI,CAAC,SAAS,CAAC,KAAK,CACnB,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,mBAAmB,CACxE,CAAC;IACH,CAAC;IAEO,aAAa;QACpB,IAAA,iBAAM,EAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,IAAY,iBAAiB;QAC5B,OAAO,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAEM,OAAO;QACb,IAAA,iBAAM,EAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC3D,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAEM,cAAc;QACpB,0GAA0G;QAC1G,6GAA6G;QAC7G,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC5B,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IAEO,sBAAsB,CAAC,QAAgB;QAC9C,2DAA2D;QAC3D,IAAI,QAAQ,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,CAAC;iBAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBACrC,2EAA2E;gBAC3E,+CAA+C;gBAC/C,0DAA0D;gBAC1D,gHAAgH;gBAChH,uFAAuF;gBACvF,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAC9B,IAAI,CAAC,UAAU,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,gBAAgB,EAAE,YAAY;gBACxF,SAAS,CACT,CAAC;YACH,CAAC;YACD,+DAA+D;YAC/D,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,IAAI,CAAC,SAAS,GAAG,2BAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;oBAC5D,SAAS,EAAE,uBAAuB;oBAClC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;wBACvB,cAAc,EAAE,IAAI,CAAC,SAAS;wBAC9B,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE;qBACvD,CAAC;iBACF,CAAC,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IAEO,sBAAsB,CAC7B,MAA6E;QAE7E,IAAA,iBAAM,EACL,IAAI,CAAC,QAAQ,KAAK,SAAS,EAC3B,KAAK,CAAC,mDAAmD,CACzD,CAAC;QAEF,IAAA,iBAAM,EACL,CAAC,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EACxD,KAAK,CAAC,gEAAgE,CACtE,CAAC;QAEF,mCAAmC;QACnC,oEAAoE;QACpE,4IAA4I;QAC5I,IACC,IAAI,CAAC,eAAe,KAAK,IAAI,CAAC,QAAQ;YACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC;YACpC,CAAC,IAAI,CAAC,iBAAiB,EACtB,CAAC;YACF,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAChC,IAAI,CAAC,kBAAkB,CAAC,oCAAe,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;aAAM,CAAC;YACP,2FAA2F;YAC3F,wFAAwF;YACxF,MAAM,KAAK,GACV,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,KAAK,oCAAe,CAAC,YAAY,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC;gBACtC,SAAS,EAAE,wBAAwB;gBACnC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;gBACrC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;oBACvB,MAAM;oBACN,eAAe,EAAE,IAAI,CAAC,eAAe;oBACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;oBACzC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC;iBAClD,CAAC;aACF,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEO,yBAAyB,CAAC,QAAgB;QACjD,8DAA8D;QAC9D,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC1D,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;QAClD,CAAC;IACF,CAAC;IAEM,uBAAuB,CAAC,MAAqD;QACnF,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,kBAAkB,CAAC,oCAAe,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC;IAEM,4BAA4B,CAAC,MAAoC;QACvE,IAAA,iBAAM,EACL,IAAI,CAAC,gBAAgB,KAAK,oCAAe,CAAC,sBAAsB,EAChE,KAAK,CAAC,uDAAuD,CAC7D,CAAC;QACF,IAAA,iBAAM,EAAC,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACnF,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,oCAAe,CAAC,YAAY,CAAC;QACrD,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,oCAAe,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrF,CAAC;IAEM,sBAAsB,CAAC,MAAoC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,oCAAe,CAAC,sBAAsB,CAAC;QAC/D,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,oCAAe,CAAC,sBAAsB,EAAE,QAAQ,EAAE;YACrF,IAAI,EAAE,kCAAkC,MAAM,CAAC,IAAI,EAAE;YACrD,KAAK,EAAE,MAAM,CAAC,KAAK;SACnB,CAAC,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,iBAAiB;QACxB,IAAA,iBAAM,EACL,IAAI,CAAC,UAAU,KAAK,SAAS,EAC7B,KAAK,CAAC,kDAAkD,CACxD,CAAC;QACF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,4BAA4B,CAAC;IAC9E,CAAC;IAED;;;;;;;OAOG;IACI,oBAAoB,CAAC,OAAmC;QAC9D,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,oCAAe,CAAC,UAAU,CAAC;QAEnD,0FAA0F;QAC1F,yFAAyF;QACzF,EAAE;QACF,oDAAoD;QACpD,mEAAmE;QACnE,gFAAgF;QAChF,qDAAqD;QACrD,+GAA+G;QAE/G,wGAAwG;QACxG,qDAAqD;QACrD,+FAA+F;QAC/F,6FAA6F;QAC7F,6FAA6F;QAC7F,2FAA2F;QAC3F,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;QAEzC,yGAAyG;QACzG,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,oCAAe,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1F,6GAA6G;QAC7G,sFAAsF;QACtF,kFAAkF;QAClF,yGAAyG;QACzG,uCAAuC;QACvC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE,CAAC;YACxE,oEAAoE;YACpE,oFAAoF;YACpF,IAAI,CAAC,cAAc,EAAE,CAAC;QACvB,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACpC,2FAA2F;YAC3F,kDAAkD;YAClD,mGAAmG;YACnG,IAAI,CAAC,kBAAkB,CAAC,oCAAe,CAAC,SAAS,CAAC,CAAC;QACpD,CAAC;QACD,sGAAsG;IACvG,CAAC;IAOO,kBAAkB,CACzB,KAA+D,EAC/D,MAAqC;QAErC,IAAI,IAAI,CAAC,eAAe,KAAK,KAAK,EAAE,CAAC;YACpC,4CAA4C;YAC5C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,SAAS,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC;YACnF,OAAO;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACvC,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAE9B,sFAAsF;QACtF,oGAAoG;QACpG,oCAAoC;QACpC,MAAM,qBAAqB,GAC1B,IAAI,CAAC,SAAS,KAAK,SAAS;YAC5B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;QAChE,IAAI,KAAK,KAAK,oCAAe,CAAC,SAAS,EAAE,CAAC;YACzC,IAAA,iBAAM,EACL,QAAQ,KAAK,oCAAe,CAAC,UAAU,EACvC,KAAK,CAAC,oDAAoD,CAC1D,CAAC;YACF,yEAAyE;YACzE,IAAI,qBAAqB,EAAE,CAAC;gBAC3B,oEAAoE;gBACpE,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC;YACpD,CAAC;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC;QACvC,CAAC;aAAM,IAAI,KAAK,KAAK,oCAAe,CAAC,YAAY,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;gBAC7B,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,CAAC;YAED,wGAAwG;YACxG,oDAAoD;YACpD,qGAAqG;YACrG,sGAAsG;YACtG,IACC,qBAAqB;gBACrB,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE;gBACpC,CAAC,IAAI,CAAC,iBAAiB,CAAC,6CAA6C;cACpE,CAAC;gBACF,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACP,2FAA2F;gBAC3F,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC;oBACtC,SAAS,EAAE,sBAAsB;oBACjC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC;wBACvB,QAAQ,EAAE,IAAI,CAAC,SAAS;wBACxB,QAAQ,EAAE,qBAAqB;wBAC/B,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;wBACzC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE;qBACvD,CAAC;iBACF,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,oBAAoB;QACpB,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,IAAI,CAAC,gBAAgB,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QAE7E,2DAA2D;QAC3D,4HAA4H;QAC5H,oJAAoJ;QACpJ,IAAI,KAAK,KAAK,oCAAe,CAAC,YAAY,EAAE,CAAC;YAC5C,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACnC,CAAC;IACF,CAAC;IAED,IAAc,UAAU;QACvB,qCAAqC;QACrC,0GAA0G;QAC1G,qHAAqH;QACrH,OAAO,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC5F,CAAC;IAEM,YAAY,CAAC,QAA0B;QAC7C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;YACtD,+FAA+F;YAC/F,+FAA+F;YAC/F,qFAAqF;YACrF,IAAA,iBAAM,EACJ,OAAmB,CAAC,IAAI,KAAK,MAAM;gBACnC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,EAClD,KAAK,CAAC,kCAAkC,CACxC,CAAC;YACF,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE;YAChD,IAAA,iBAAM,EACL,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,SAAS,EACjD,KAAK,CAAC,kCAAkC,CACxC,CAAC;YACF,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QAEH;;;;;;UAMQ;QACR,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAC1C,oEAAoE;YACpE,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAgB,CAAC,CAAC;QACpD,CAAC;QAED,IAAA,iBAAM,EACL,CAAC,IAAI,CAAC,iBAAiB,EACvB,KAAK,CAAC,kEAAkE,CACxE,CAAC;QAEF,4GAA4G;QAC5G,0EAA0E;QAC1E,wFAAwF;QACxF,6CAA6C;QAC7C,4EAA4E;QAC5E,kGAAkG;QAClG,oGAAoG;QACpG,wGAAwG;QACxG,kDAAkD;QAClD,IACC,IAAI,CAAC,SAAS,KAAK,SAAS;YAC5B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,EACvD,CAAC;YACF,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC;IACF,CAAC;IAES,SAAS,CAAC,QAAiB;QACpC,OAAO,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC;IACjE,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport { assert, Timer } from \"@fluidframework/core-utils/internal\";\nimport { IClient, ISequencedClient } from \"@fluidframework/driver-definitions\";\nimport { IAnyDriverError } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype TelemetryEventCategory,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { CatchUpMonitor, ICatchUpMonitor } from \"./catchUpMonitor.js\";\nimport { ConnectionState } from \"./connectionState.js\";\nimport { IConnectionDetailsInternal, IConnectionStateChangeReason } from \"./contracts.js\";\nimport { IProtocolHandler } from \"./protocol.js\";\n\n// Based on recent data, it looks like majority of cases where we get stuck are due to really slow or\n// timing out ops fetches. So attempt recovery infrequently. Also fetch uses 30 second timeout, so\n// if retrying fixes the problem, we should not see these events.\nconst JoinOpTimeoutMs = 45000;\n\n// Timeout waiting for \"self\" join signal, before giving up\nconst JoinSignalTimeoutMs = 10000;\n\n/** Constructor parameter type for passing in dependencies needed by the ConnectionStateHandler */\nexport interface IConnectionStateHandlerInputs {\n\tlogger: ITelemetryLoggerExt;\n\tmc: MonitoringContext;\n\t/** Log to telemetry any change in state, included to Connecting */\n\tconnectionStateChanged: (\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason,\n\t) => void;\n\t/** Whether to expect the client to join in write mode on next connection */\n\tshouldClientJoinWrite: () => boolean;\n\t/** (Optional) How long should we wait on our previous client's Leave op before transitioning to Connected again */\n\tmaxClientLeaveWaitTime: number | undefined;\n\t/** Log an issue encountered while in the Connecting state. details will be logged as a JSON string */\n\tlogConnectionIssue: (\n\t\teventName: string,\n\t\tcategory: TelemetryEventCategory,\n\t\tdetails?: ITelemetryBaseProperties,\n\t) => void;\n\t/** Callback to note that an old local client ID is still present in the Quorum that should have left and should now be considered invalid */\n\tclientShouldHaveLeft: (clientId: string) => void;\n\n\t/** Some critical error was hit. Container should be closed and error logged. */\n\tonCriticalError: (error: unknown) => void;\n}\n\n/**\n * interface that connection state handler implements\n */\nexport interface IConnectionStateHandler {\n\treadonly connectionState: ConnectionState;\n\t/**\n\t * Pending clientID.\n\t * Changes whenever socket connection is established.\n\t * Resets to undefined when connection is lost\n\t */\n\treadonly pendingClientId: string | undefined;\n\t/**\n\t * clientId of a last established connection.\n\t * Does not reset on disconnect.\n\t * Changes only when new connection is established, client is fully caught up, and\n\t * there is no chance to ops from previous connection (i.e. if needed, we have waited and observed leave op from previous connection)\n\t */\n\treadonly clientId: string | undefined;\n\n\tcontainerSaved(): void;\n\tdispose(): void;\n\tinitProtocol(protocol: IProtocolHandler): void;\n\treceivedConnectEvent(details: IConnectionDetailsInternal): void;\n\treceivedDisconnectEvent(reason: IConnectionStateChangeReason): void;\n\testablishingConnection(reason: IConnectionStateChangeReason): void;\n\t/**\n\t * Switches state to disconnected when we are still establishing connection during container.load(),\n\t * container connect() or reconnect and the container gets closed or disposed or disconnect happens.\n\t * @param reason - reason for cancelling the connection.\n\t */\n\tcancelEstablishingConnection(reason: IConnectionStateChangeReason): void;\n}\n\nexport function createConnectionStateHandler(\n\tinputs: IConnectionStateHandlerInputs,\n\tdeltaManager: IDeltaManager<any, any>,\n\tclientId?: string,\n) {\n\tconst config = inputs.mc.config;\n\treturn createConnectionStateHandlerCore(\n\t\tconfig.getBoolean(\"Fluid.Container.DisableCatchUpBeforeDeclaringConnected\") !== true, // connectedRaisedWhenCaughtUp\n\t\tconfig.getBoolean(\"Fluid.Container.DisableJoinSignalWait\") !== true, // readClientsWaitForJoinSignal\n\t\tinputs,\n\t\tdeltaManager,\n\t\tclientId,\n\t);\n}\n\nexport function createConnectionStateHandlerCore(\n\tconnectedRaisedWhenCaughtUp: boolean,\n\treadClientsWaitForJoinSignal: boolean,\n\tinputs: IConnectionStateHandlerInputs,\n\tdeltaManager: IDeltaManager<any, any>,\n\tclientId?: string,\n) {\n\tconst factory = (handler: IConnectionStateHandlerInputs) =>\n\t\tnew ConnectionStateHandler(handler, readClientsWaitForJoinSignal, clientId);\n\n\treturn connectedRaisedWhenCaughtUp\n\t\t? new ConnectionStateCatchup(inputs, factory, deltaManager)\n\t\t: factory(inputs);\n}\n\n/**\n * Helper internal interface to abstract away Audience & Quorum\n */\ninterface IMembership {\n\ton(\n\t\teventName: \"addMember\" | \"removeMember\",\n\t\tlistener: (clientId: string, details: IClient | ISequencedClient) => void,\n\t);\n\tgetMember(clientId: string): undefined | unknown;\n}\n\n/**\n * Class that can be used as a base class for building IConnectionStateHandler adapters / pipeline.\n * It implements both ends of communication interfaces and passes data back and forward\n */\nclass ConnectionStateHandlerPassThrough\n\timplements IConnectionStateHandler, IConnectionStateHandlerInputs\n{\n\tprotected readonly pimpl: IConnectionStateHandler;\n\n\tconstructor(\n\t\tprotected readonly inputs: IConnectionStateHandlerInputs,\n\t\tpimplFactory: (handler: IConnectionStateHandlerInputs) => IConnectionStateHandler,\n\t) {\n\t\tthis.pimpl = pimplFactory(this);\n\t}\n\n\t/**\n\t * IConnectionStateHandler\n\t */\n\tpublic get connectionState() {\n\t\treturn this.pimpl.connectionState;\n\t}\n\tpublic get pendingClientId() {\n\t\treturn this.pimpl.pendingClientId;\n\t}\n\tpublic get clientId() {\n\t\treturn this.pimpl.clientId;\n\t}\n\n\tpublic containerSaved() {\n\t\treturn this.pimpl.containerSaved();\n\t}\n\tpublic dispose() {\n\t\treturn this.pimpl.dispose();\n\t}\n\tpublic initProtocol(protocol: IProtocolHandler) {\n\t\treturn this.pimpl.initProtocol(protocol);\n\t}\n\tpublic receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>) {\n\t\treturn this.pimpl.receivedDisconnectEvent(reason);\n\t}\n\n\tpublic establishingConnection(reason: IConnectionStateChangeReason) {\n\t\treturn this.pimpl.establishingConnection(reason);\n\t}\n\n\tpublic cancelEstablishingConnection(reason: IConnectionStateChangeReason) {\n\t\treturn this.pimpl.cancelEstablishingConnection(reason);\n\t}\n\n\tpublic receivedConnectEvent(details: IConnectionDetailsInternal) {\n\t\treturn this.pimpl.receivedConnectEvent(details);\n\t}\n\n\t/**\n\t * IConnectionStateHandlerInputs\n\t */\n\n\tpublic get logger() {\n\t\treturn this.inputs.logger;\n\t}\n\tpublic get mc() {\n\t\treturn this.inputs.mc;\n\t}\n\tpublic connectionStateChanged(\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason,\n\t) {\n\t\treturn this.inputs.connectionStateChanged(value, oldState, reason);\n\t}\n\tpublic shouldClientJoinWrite() {\n\t\treturn this.inputs.shouldClientJoinWrite();\n\t}\n\tpublic get maxClientLeaveWaitTime() {\n\t\treturn this.inputs.maxClientLeaveWaitTime;\n\t}\n\tpublic logConnectionIssue(\n\t\teventName: string,\n\t\tcategory: TelemetryEventCategory,\n\t\tdetails?: ITelemetryBaseProperties,\n\t) {\n\t\treturn this.inputs.logConnectionIssue(eventName, category, details);\n\t}\n\tpublic clientShouldHaveLeft(clientId: string) {\n\t\treturn this.inputs.clientShouldHaveLeft(clientId);\n\t}\n\n\tpublic onCriticalError(error: unknown) {\n\t\treturn this.inputs.onCriticalError(error);\n\t}\n}\n\n/**\n * Implementation of IConnectionStateHandler pass-through adapter that waits for specific sequence number\n * before raising connected event\n */\nclass ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {\n\tprivate catchUpMonitor: ICatchUpMonitor | undefined;\n\n\tconstructor(\n\t\tinputs: IConnectionStateHandlerInputs,\n\t\tpimplFactory: (handler: IConnectionStateHandlerInputs) => IConnectionStateHandler,\n\t\tprivate readonly deltaManager: IDeltaManager<any, any>,\n\t) {\n\t\tsuper(inputs, pimplFactory);\n\t\tthis._connectionState = this.pimpl.connectionState;\n\t}\n\n\tprivate _connectionState: ConnectionState;\n\tpublic get connectionState() {\n\t\treturn this._connectionState;\n\t}\n\n\tpublic connectionStateChanged(\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason<IAnyDriverError>,\n\t) {\n\t\tswitch (value) {\n\t\t\tcase ConnectionState.Connected:\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.CatchingUp,\n\t\t\t\t\t0x3e1 /* connectivity transitions */,\n\t\t\t\t);\n\t\t\t\t// Create catch-up monitor here (not earlier), as we might get more exact info by now about how far\n\t\t\t\t// client is behind through join signal. This is only true if base layer uses signals (i.e. audience,\n\t\t\t\t// not quorum, including for \"rea\" connections) to make decisions about moving to \"connected\" state.\n\t\t\t\t// In addition to that, in its current form, doing this in ConnectionState.CatchingUp is dangerous as\n\t\t\t\t// we might get callback right away, and it will screw up state transition (as code outside of switch\n\t\t\t\t// statement will overwrite current state).\n\t\t\t\tassert(this.catchUpMonitor === undefined, 0x3eb /* catchUpMonitor should be gone */);\n\t\t\t\tthis.catchUpMonitor = new CatchUpMonitor(\n\t\t\t\t\tthis.deltaManager,\n\t\t\t\t\tthis.transitionToConnectedState,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\tcase ConnectionState.Disconnected:\n\t\t\t\tthis.catchUpMonitor?.dispose();\n\t\t\t\tthis.catchUpMonitor = undefined;\n\t\t\t\tbreak;\n\t\t\t// ConnectionState.EstablishingConnection state would be set when we start establishing connection\n\t\t\t// during container.connect() or reconnect because of an error.\n\t\t\tcase ConnectionState.EstablishingConnection:\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.Disconnected,\n\t\t\t\t\t0x6d2 /* connectivity transition to establishing connection */,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase ConnectionState.CatchingUp:\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.EstablishingConnection,\n\t\t\t\t\t0x3e3 /* connectivity transitions */,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t}\n\t\tthis._connectionState = value;\n\t\tthis.inputs.connectionStateChanged(value, oldState, reason);\n\t}\n\n\tprivate readonly transitionToConnectedState = () => {\n\t\t// Defensive measure, we should always be in Connecting state when this is called.\n\t\tconst state = this.pimpl.connectionState;\n\t\tassert(state === ConnectionState.Connected, 0x3e5 /* invariant broken */);\n\t\tassert(this._connectionState === ConnectionState.CatchingUp, 0x3e6 /* invariant broken */);\n\t\tthis._connectionState = ConnectionState.Connected;\n\t\tthis.inputs.connectionStateChanged(ConnectionState.Connected, ConnectionState.CatchingUp, {\n\t\t\ttext: \"caught up\",\n\t\t});\n\t};\n}\n\n/**\n * In the lifetime of a container, the connection will likely disconnect and reconnect periodically.\n * This class ensures that any ops sent by this container instance on previous connection are either\n * sequenced or blocked by the server before emitting the new \"connected\" event and allowing runtime to resubmit ops.\n *\n * Each connection is assigned a clientId by the service, and the connection is book-ended by a Join and a Leave op\n * generated by the service. Due to the distributed nature of the Relay Service, in the case of reconnect we cannot\n * make any assumptions about ordering of operations between the old and new connections - i.e. new Join op could\n * be sequenced before old Leave op (and some acks from pending ops that were in flight when we disconnected).\n *\n * The job of this class is to encapsulate the transition period during reconnect, which is identified by\n * ConnectionState.CatchingUp. Specifically, before moving to Connected state with the new clientId, it ensures that:\n *\n * a. We process the Leave op for the previous clientId. This allows us to properly handle any acks from in-flight ops\n * that got sequenced with the old clientId (we'll recognize them as local ops). After the Leave op, any other\n * pending ops can safely be submitted with the new clientId without fear of duplication in the sequenced op stream.\n *\n * b. We process the Join op for the new clientId (identified when the underlying connection was first established),\n * indicating the service is ready to sequence ops sent with the new clientId.\n *\n * c. We process all ops known at the time the underlying connection was established (so we are \"caught up\")\n *\n * For (a) we give up waiting after some time (same timeout as server uses), and go ahead and transition to Connected.\n *\n * For (b) we log telemetry if it takes too long, but still only transition to Connected when the Join op/signal is\n * processed.\n *\n * For (c) this is optional behavior, controlled by the parameters of receivedConnectEvent\n */\nclass ConnectionStateHandler implements IConnectionStateHandler {\n\tprivate _connectionState = ConnectionState.Disconnected;\n\tprivate _pendingClientId: string | undefined;\n\n\t/**\n\t * Tracks that we observe the \"leave\" op within the timeout for our previous clientId (see comment on ConnectionStateHandler class)\n\t * ! This ensures we do not switch to a new clientId until we process all potential messages from old clientId\n\t * ! i.e. We will always see the \"leave\" op for a client after we have seen all the ops it has sent\n\t * ! This check helps prevent the same op from being resubmitted by the PendingStateManager upon reconnecting\n\t */\n\tprivate readonly prevClientLeftTimer: Timer;\n\n\t/**\n\t * Tracks that we observe our own \"join\" op within the timeout after receiving a \"connected\" event from the DeltaManager\n\t */\n\tprivate readonly joinTimer: Timer;\n\n\tprivate protocol?: IProtocolHandler;\n\tprivate connection?: IConnectionDetailsInternal;\n\tprivate _clientId?: string;\n\n\t/** Track how long we waited to see \"leave\" op for previous clientId */\n\tprivate waitEvent: PerformanceEvent | undefined;\n\n\tpublic get connectionState(): ConnectionState {\n\t\treturn this._connectionState;\n\t}\n\n\tpublic get clientId(): string | undefined {\n\t\treturn this._clientId;\n\t}\n\n\tpublic get pendingClientId(): string | undefined {\n\t\treturn this._pendingClientId;\n\t}\n\n\tconstructor(\n\t\tprivate readonly handler: IConnectionStateHandlerInputs,\n\t\tprivate readonly readClientsWaitForJoinSignal: boolean,\n\t\tclientIdFromPausedSession?: string,\n\t) {\n\t\tthis._clientId = clientIdFromPausedSession;\n\t\tconst errorHandler = (error) => this.handler.onCriticalError(error);\n\t\tthis.prevClientLeftTimer = new Timer(\n\t\t\t// Default is 5 min for which we are going to wait for its own \"leave\" message. This is same as\n\t\t\t// the max time on server after which leave op is sent.\n\t\t\tthis.handler.maxClientLeaveWaitTime ?? 300000,\n\t\t\t() => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.connectionState !== ConnectionState.Connected,\n\t\t\t\t\t0x2ac /* \"Connected when timeout waiting for leave from previous session fired!\" */,\n\t\t\t\t);\n\t\t\t\tthis.applyForConnectedState(\"timeout\");\n\t\t\t},\n\t\t\terrorHandler,\n\t\t);\n\n\t\tthis.joinTimer = new Timer(\n\t\t\t0, // default value is not used - startjoinTimer() explicitly provides timeout\n\t\t\t() => {\n\t\t\t\t// I've observed timer firing within couple ms from disconnect event, looks like\n\t\t\t\t// queued timer callback is not cancelled if timer is cancelled while callback sits in the queue.\n\t\t\t\tif (this.connectionState !== ConnectionState.CatchingUp) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst details = {\n\t\t\t\t\tprotocolInitialized: this.protocol !== undefined,\n\t\t\t\t\tpendingClientId: this.pendingClientId,\n\t\t\t\t\tclientJoined: this.hasMember(this.pendingClientId),\n\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t};\n\t\t\t\tthis.handler.logConnectionIssue(\n\t\t\t\t\tthis.connection?.mode === \"read\" ? \"NoJoinSignal\" : \"NoJoinOp\", // eventName\n\t\t\t\t\t\"error\", // category\n\t\t\t\t\tdetails,\n\t\t\t\t);\n\t\t\t},\n\t\t\terrorHandler,\n\t\t);\n\t}\n\n\tprivate startjoinTimer() {\n\t\tassert(!this.joinTimer.hasTimer, 0x234 /* \"has joinTimer\" */);\n\t\tassert(this.connection !== undefined, 0x4b3 /* have connection */);\n\t\tthis.joinTimer.start(\n\t\t\tthis.connection.mode === \"write\" ? JoinOpTimeoutMs : JoinSignalTimeoutMs,\n\t\t);\n\t}\n\n\tprivate stopjoinTimer() {\n\t\tassert(this.joinTimer.hasTimer, 0x235 /* \"no joinTimer\" */);\n\t\tthis.joinTimer.clear();\n\t}\n\n\tprivate get waitingForLeaveOp() {\n\t\treturn this.prevClientLeftTimer.hasTimer;\n\t}\n\n\tpublic dispose() {\n\t\tassert(!this.joinTimer.hasTimer, 0x2a5 /* \"join timer\" */);\n\t\tthis.prevClientLeftTimer.clear();\n\t}\n\n\tpublic containerSaved() {\n\t\t// If we were waiting for moving to Connected state, then only apply for state change. Since the container\n\t\t// is now saved and we don't have any ops to roundtrip, we can clear the timer and apply for connected state.\n\t\tif (this.waitingForLeaveOp) {\n\t\t\tthis.prevClientLeftTimer.clear();\n\t\t\tthis.applyForConnectedState(\"containerSaved\");\n\t\t}\n\t}\n\n\tprivate receivedAddMemberEvent(clientId: string) {\n\t\t// This is the only one that requires the pending client ID\n\t\tif (clientId === this.pendingClientId) {\n\t\t\tif (this.joinTimer.hasTimer) {\n\t\t\t\tthis.stopjoinTimer();\n\t\t\t} else if (this.shouldWaitForSelf()) {\n\t\t\t\t// timer has already fired, meaning it took too long to get join op/signal.\n\t\t\t\t// Record how long it actually took to recover.\n\t\t\t\t// This is generic event, as it by itself is not an error.\n\t\t\t\t// We also have a case where NoJoinOp happens during container boot (we do not report it as error in such case),\n\t\t\t\t// if this log statement happens after boot - we do not want to consider it error case.\n\t\t\t\tthis.handler.logConnectionIssue(\n\t\t\t\t\tthis.connection?.mode === \"read\" ? \"ReceivedJoinSignal\" : \"ReceivedJoinOp\", // eventName\n\t\t\t\t\t\"generic\", // category\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Start the event in case we are waiting for leave or timeout.\n\t\t\tif (this.waitingForLeaveOp) {\n\t\t\t\tthis.waitEvent = PerformanceEvent.start(this.handler.logger, {\n\t\t\t\t\teventName: \"WaitBeforeClientLeave\",\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\twaitOnClientId: this._clientId,\n\t\t\t\t\t\thadOutstandingOps: this.handler.shouldClientJoinWrite(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.applyForConnectedState(\"addMemberEvent\");\n\t\t}\n\t}\n\n\tprivate applyForConnectedState(\n\t\tsource: \"removeMemberEvent\" | \"addMemberEvent\" | \"timeout\" | \"containerSaved\",\n\t) {\n\t\tassert(\n\t\t\tthis.protocol !== undefined,\n\t\t\t0x236 /* \"In all cases it should be already installed\" */,\n\t\t);\n\n\t\tassert(\n\t\t\t!this.waitingForLeaveOp || this.hasMember(this.clientId),\n\t\t\t0x2e2 /* \"Must only wait for leave message when clientId in quorum\" */,\n\t\t);\n\n\t\t// Move to connected state only if:\n\t\t// 1. We have seen our own \"join\" op (i.e. for this.pendingClientId)\n\t\t// 2. There is no \"leave\" timer running, meaning this is our first connection or the previous client has left (via this.prevClientLeftTimer)\n\t\tif (\n\t\t\tthis.pendingClientId !== this.clientId &&\n\t\t\tthis.hasMember(this.pendingClientId) &&\n\t\t\t!this.waitingForLeaveOp\n\t\t) {\n\t\t\tthis.waitEvent?.end({ source });\n\t\t\tthis.setConnectionState(ConnectionState.Connected);\n\t\t} else {\n\t\t\t// Adding this event temporarily so that we can get help debugging if something goes wrong.\n\t\t\t// We may not see any ops due to being disconnected all that time - that's not an error!\n\t\t\tconst error =\n\t\t\t\tsource === \"timeout\" && this.connectionState !== ConnectionState.Disconnected;\n\t\t\tthis.handler.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"connectedStateRejected\",\n\t\t\t\tcategory: error ? \"error\" : \"generic\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tsource,\n\t\t\t\t\tpendingClientId: this.pendingClientId,\n\t\t\t\t\tclientId: this.clientId,\n\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t\tclientJoined: this.hasMember(this.pendingClientId),\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate receivedRemoveMemberEvent(clientId: string) {\n\t\t// If the client which has left was us, then finish the timer.\n\t\tif (this.clientId === clientId && this.waitingForLeaveOp) {\n\t\t\tthis.prevClientLeftTimer.clear();\n\t\t\tthis.applyForConnectedState(\"removeMemberEvent\");\n\t\t}\n\t}\n\n\tpublic receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>) {\n\t\tthis.connection = undefined;\n\t\tthis.setConnectionState(ConnectionState.Disconnected, reason);\n\t}\n\n\tpublic cancelEstablishingConnection(reason: IConnectionStateChangeReason) {\n\t\tassert(\n\t\t\tthis._connectionState === ConnectionState.EstablishingConnection,\n\t\t\t0x6d3 /* Connection state should be EstablishingConnection */,\n\t\t);\n\t\tassert(this.connection === undefined, 0x6d4 /* No connection should be present */);\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.Disconnected;\n\t\tthis.handler.connectionStateChanged(ConnectionState.Disconnected, oldState, reason);\n\t}\n\n\tpublic establishingConnection(reason: IConnectionStateChangeReason) {\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.EstablishingConnection;\n\t\tthis.handler.connectionStateChanged(ConnectionState.EstablishingConnection, oldState, {\n\t\t\ttext: `Establishing Connection due to ${reason.text}`,\n\t\t\terror: reason.error,\n\t\t});\n\t}\n\n\t/**\n\t * Tells if need to wait for \"self\" to show up in audience.\n\t * @returns - true if we should wait for \"self\" to appear in audience.\n\t * false is returned only for \"read\" connections, and only if this.readClientsWaitForJoinSignal is false.\n\t */\n\tprivate shouldWaitForSelf() {\n\t\tassert(\n\t\t\tthis.connection !== undefined,\n\t\t\t0x4b4 /* all callers call here with active connection */,\n\t\t);\n\t\treturn this.connection.mode === \"write\" || this.readClientsWaitForJoinSignal;\n\t}\n\n\t/**\n\t * The \"connect\" event indicates the connection to the Relay Service is live.\n\t * However, some additional conditions must be met before we can fully transition to\n\t * \"Connected\" state. This function handles that interim period, known as \"Connecting\" state.\n\t * @param details - Connection details returned from the Relay Service\n\t * @param deltaManager - DeltaManager to be used for delaying Connected transition until caught up.\n\t * If it's undefined, then don't delay and transition to Connected as soon as Leave/Join op are accounted for\n\t */\n\tpublic receivedConnectEvent(details: IConnectionDetailsInternal) {\n\t\tthis.connection = details;\n\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.CatchingUp;\n\n\t\t// The following checks are wrong. They are only valid if user has write access to a file.\n\t\t// If user lost such access mid-session, user will not be able to get \"write\" connection.\n\t\t//\n\t\t// const writeConnection = details.mode === \"write\";\n\t\t// assert(!this.handler.shouldClientJoinWrite() || writeConnection,\n\t\t// 0x30a /* shouldClientJoinWrite should imply this is a writeConnection */);\n\t\t// assert(!this.waitingForLeaveOp || writeConnection,\n\t\t// 0x2a6 /* \"waitingForLeaveOp should imply writeConnection (we need to be ready to flush pending ops)\" */);\n\n\t\t// Stash the clientID to detect when transitioning from connecting (socket.io channel open) to connected\n\t\t// (have received the join message for the client ID)\n\t\t// This is especially important in the reconnect case. It's possible there could be outstanding\n\t\t// ops sent by this client, so we should keep the old client id until we see our own client's\n\t\t// join message. after we see the join message for our new connection with our new client id,\n\t\t// we know there can no longer be outstanding ops that we sent with the previous client id.\n\t\tthis._pendingClientId = details.clientId;\n\n\t\t// IMPORTANT: Report telemetry after we set _pendingClientId, but before transitioning to Connected state\n\t\tthis.handler.connectionStateChanged(ConnectionState.CatchingUp, oldState, details.reason);\n\n\t\t// Check if we need to wait for join op/signal, and if we need to wait for leave op from previous connection.\n\t\t// Pending clientId could have joined already (i.e. join op/signal already processed):\n\t\t// We are fetching ops from storage in parallel to connecting to Relay Service,\n\t\t// and given async processes, it's possible that we have already processed our own join message before\n\t\t// connection was fully established.\n\t\tif (!this.hasMember(this._pendingClientId) && this.shouldWaitForSelf()) {\n\t\t\t// We are waiting for our own join op / signal. When it is processed\n\t\t\t// we'll attempt to transition to Connected state via receivedAddMemberEvent() flow.\n\t\t\tthis.startjoinTimer();\n\t\t} else if (!this.waitingForLeaveOp) {\n\t\t\t// We're not waiting for Join or Leave op (if read-only connection those don't even apply),\n\t\t\t// go ahead and declare the state to be Connected!\n\t\t\t// If we are waiting for Leave op still, do nothing for now, we will transition to Connected later.\n\t\t\tthis.setConnectionState(ConnectionState.Connected);\n\t\t}\n\t\t// else - We are waiting for Leave op still, do nothing for now, we will transition to Connected later\n\t}\n\n\tprivate setConnectionState(\n\t\tvalue: ConnectionState.Disconnected,\n\t\treason: IConnectionStateChangeReason,\n\t): void;\n\tprivate setConnectionState(value: ConnectionState.Connected): void;\n\tprivate setConnectionState(\n\t\tvalue: ConnectionState.Disconnected | ConnectionState.Connected,\n\t\treason?: IConnectionStateChangeReason,\n\t): void {\n\t\tif (this.connectionState === value) {\n\t\t\t// Already in the desired state - exit early\n\t\t\tthis.handler.logger.sendErrorEvent({ eventName: \"setConnectionStateSame\", value });\n\t\t\treturn;\n\t\t}\n\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = value;\n\n\t\t// This is the only place in code that deals with quorum. The rest works with audience\n\t\t// The code below ensures that we do not send ops until we know that old \"write\" client's disconnect\n\t\t// produced (and sequenced) leave op\n\t\tconst currentClientInQuorum =\n\t\t\tthis._clientId !== undefined &&\n\t\t\tthis.protocol?.quorum?.getMember(this._clientId) !== undefined;\n\t\tif (value === ConnectionState.Connected) {\n\t\t\tassert(\n\t\t\t\toldState === ConnectionState.CatchingUp,\n\t\t\t\t0x1d8 /* \"Should only transition from Connecting state\" */,\n\t\t\t);\n\t\t\t// Mark our old client should have left in the quorum if it's still there\n\t\t\tif (currentClientInQuorum) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.handler.clientShouldHaveLeft(this._clientId!);\n\t\t\t}\n\t\t\tthis._clientId = this.pendingClientId;\n\t\t} else if (value === ConnectionState.Disconnected) {\n\t\t\tif (this.joinTimer.hasTimer) {\n\t\t\t\tthis.stopjoinTimer();\n\t\t\t}\n\n\t\t\t// Only wait for \"leave\" message if the connected client exists in the quorum and had some non-acked ops\n\t\t\t// Also check if the timer is not already running as\n\t\t\t// we could receive \"Disconnected\" event multiple times without getting connected and in that case we\n\t\t\t// don't want to reset the timer as we still want to wait on original client which started this timer.\n\t\t\tif (\n\t\t\t\tcurrentClientInQuorum &&\n\t\t\t\tthis.handler.shouldClientJoinWrite() &&\n\t\t\t\t!this.waitingForLeaveOp // same as !this.prevClientLeftTimer.hasTimer\n\t\t\t) {\n\t\t\t\tthis.prevClientLeftTimer.restart();\n\t\t\t} else {\n\t\t\t\t// Adding this event temporarily so that we can get help debugging if something goes wrong.\n\t\t\t\tthis.handler.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"noWaitOnDisconnected\",\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tclientId: this._clientId,\n\t\t\t\t\t\tinQuorum: currentClientInQuorum,\n\t\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t\t\thadOutstandingOps: this.handler.shouldClientJoinWrite(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Report transition\n\t\tthis.handler.connectionStateChanged(this._connectionState, oldState, reason);\n\n\t\t// Clear pending state immediately to prepare for reconnect\n\t\t// Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events\n\t\t// and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)\n\t\tif (value === ConnectionState.Disconnected) {\n\t\t\tthis._pendingClientId = undefined;\n\t\t}\n\t}\n\n\tprotected get membership(): IMembership | undefined {\n\t\t// We could always use audience here.\n\t\t// This is true because Audience is a superset of quorum, i.e. when we filter Audience to \"write\" clients,\n\t\t// it is exactly the same as quorum! Please see asserts in Audience callbacks setup by initProtocol() enforcing that.\n\t\treturn this.readClientsWaitForJoinSignal ? this.protocol?.audience : this.protocol?.quorum;\n\t}\n\n\tpublic initProtocol(protocol: IProtocolHandler) {\n\t\tthis.protocol = protocol;\n\n\t\tthis.membership?.on(\"addMember\", (clientId, details) => {\n\t\t\t// This is very important constrain. We rely on it when testing presence of \"self\" in Audience.\n\t\t\t// We do not want to move to \"connected\" state for \"write\" connections when JoinSignal shows up\n\t\t\t// for \"self\" - we want to move to \"connected\" state only when \"join\" op is received.\n\t\t\tassert(\n\t\t\t\t(details as IClient).mode === \"read\" ||\n\t\t\t\t\tprotocol.quorum.getMember(clientId) !== undefined,\n\t\t\t\t0x4b5 /* Audience is subset of quorum */,\n\t\t\t);\n\t\t\tthis.receivedAddMemberEvent(clientId);\n\t\t});\n\n\t\tthis.membership?.on(\"removeMember\", (clientId) => {\n\t\t\tassert(\n\t\t\t\tprotocol.quorum.getMember(clientId) === undefined,\n\t\t\t\t0x4b6 /* Audience is subset of quorum */,\n\t\t\t);\n\t\t\tthis.receivedRemoveMemberEvent(clientId);\n\t\t});\n\n\t\t/* There is a tiny tiny race possible, where these events happen in this order:\n 1. A connection is established (no \"cached\" mode is used, so it happens in parallel / faster than other steps)\n 2. Some other client produces a summary\n 3. We get \"lucky\" and load from that summary as our initial snapshot\n 4. ConnectionStateHandler.initProtocol is called, \"self\" is already in the quorum.\n We could avoid this sequence (and delete test case for it) if we move connection lower in Container.load()\n */\n\t\tif (this.hasMember(this.pendingClientId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.receivedAddMemberEvent(this.pendingClientId!);\n\t\t}\n\n\t\tassert(\n\t\t\t!this.waitingForLeaveOp,\n\t\t\t0x99d /* leave timer can't be set as we have not had access to quorum */,\n\t\t);\n\n\t\t// This check is required for scenario of loading container from pending state, and ensuring there is no way\n\t\t// old clientId is still in the quorum (very unlikely, but you never know)\n\t\t// if we have a clientId from a previous container we need to wait for its leave message\n\t\t// This mimicks check in setConnectionState()\n\t\t// Note that we are not consulting this.handler.shouldClientJoinWrite() here\n\t\t// It could produce wrong results for stashed ops were never sent to Loader yet, and if this check\n\t\t// makes determination only on that (and not uses \"dirty\" events), then it can produce wrong result.\n\t\t// In most cases it does not matter, as this client already left quorum. But in really unfortunate case,\n\t\t// we might wait even if we could avoid such wait.\n\t\tif (\n\t\t\tthis._clientId !== undefined &&\n\t\t\tprotocol.quorum?.getMember(this._clientId) !== undefined\n\t\t) {\n\t\t\tthis.prevClientLeftTimer.restart();\n\t\t}\n\t}\n\n\tprotected hasMember(clientId?: string) {\n\t\treturn this.membership?.getMember(clientId ?? \"\") !== undefined;\n\t}\n}\n"]}
1
+ {"version":3,"file":"connectionStateHandler.js","sourceRoot":"","sources":["../src/connectionStateHandler.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDeltaManager } from \"@fluidframework/container-definitions/internal\";\nimport { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport { assert, Timer } from \"@fluidframework/core-utils/internal\";\nimport { IClient, ISequencedClient } from \"@fluidframework/driver-definitions\";\nimport { IAnyDriverError } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\ttype TelemetryEventCategory,\n\tITelemetryLoggerExt,\n\tMonitoringContext,\n\tPerformanceEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\n\nimport { CatchUpMonitor, ICatchUpMonitor } from \"./catchUpMonitor.js\";\nimport { ConnectionState } from \"./connectionState.js\";\nimport { IConnectionDetailsInternal, IConnectionStateChangeReason } from \"./contracts.js\";\nimport { IProtocolHandler } from \"./protocol.js\";\n\n// Based on recent data, it looks like majority of cases where we get stuck are due to really slow or\n// timing out ops fetches. So attempt recovery infrequently. Also fetch uses 30 second timeout, so\n// if retrying fixes the problem, we should not see these events.\nconst JoinOpTimeoutMs = 45000;\n\n// Timeout waiting for \"self\" join signal, before giving up\nconst JoinSignalTimeoutMs = 10000;\n\n/**\n * Constructor parameter type for passing in dependencies needed by the ConnectionStateHandler\n */\nexport interface IConnectionStateHandlerInputs {\n\tlogger: ITelemetryLoggerExt;\n\tmc: MonitoringContext;\n\t/**\n\t * Log to telemetry any change in state, included to Connecting\n\t */\n\tconnectionStateChanged: (\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason,\n\t) => void;\n\t/**\n\t * Whether to expect the client to join in write mode on next connection\n\t */\n\tshouldClientJoinWrite: () => boolean;\n\t/**\n\t * (Optional) How long should we wait on our previous client's Leave op before transitioning to Connected again\n\t */\n\tmaxClientLeaveWaitTime: number | undefined;\n\t/**\n\t * Log an issue encountered while in the Connecting state. details will be logged as a JSON string\n\t */\n\tlogConnectionIssue: (\n\t\teventName: string,\n\t\tcategory: TelemetryEventCategory,\n\t\tdetails?: ITelemetryBaseProperties,\n\t) => void;\n\t/**\n\t * Callback to note that an old local client ID is still present in the Quorum that should have left and should now be considered invalid\n\t */\n\tclientShouldHaveLeft: (clientId: string) => void;\n\n\t/**\n\t * Some critical error was hit. Container should be closed and error logged.\n\t */\n\tonCriticalError: (error: unknown) => void;\n}\n\n/**\n * interface that connection state handler implements\n */\nexport interface IConnectionStateHandler {\n\treadonly connectionState: ConnectionState;\n\t/**\n\t * Pending clientID.\n\t * Changes whenever socket connection is established.\n\t * Resets to undefined when connection is lost\n\t */\n\treadonly pendingClientId: string | undefined;\n\t/**\n\t * clientId of a last established connection.\n\t * Does not reset on disconnect.\n\t * Changes only when new connection is established, client is fully caught up, and\n\t * there is no chance to ops from previous connection (i.e. if needed, we have waited and observed leave op from previous connection)\n\t */\n\treadonly clientId: string | undefined;\n\n\tcontainerSaved(): void;\n\tdispose(): void;\n\tinitProtocol(protocol: IProtocolHandler): void;\n\treceivedConnectEvent(details: IConnectionDetailsInternal): void;\n\treceivedDisconnectEvent(reason: IConnectionStateChangeReason): void;\n\testablishingConnection(reason: IConnectionStateChangeReason): void;\n\t/**\n\t * Switches state to disconnected when we are still establishing connection during container.load(),\n\t * container connect() or reconnect and the container gets closed or disposed or disconnect happens.\n\t * @param reason - reason for cancelling the connection.\n\t */\n\tcancelEstablishingConnection(reason: IConnectionStateChangeReason): void;\n}\n\nexport function createConnectionStateHandler(\n\tinputs: IConnectionStateHandlerInputs,\n\tdeltaManager: IDeltaManager<unknown, unknown>,\n\tclientId?: string,\n): ConnectionStateHandler | ConnectionStateCatchup {\n\tconst config = inputs.mc.config;\n\treturn createConnectionStateHandlerCore(\n\t\tconfig.getBoolean(\"Fluid.Container.DisableCatchUpBeforeDeclaringConnected\") !== true, // connectedRaisedWhenCaughtUp\n\t\tconfig.getBoolean(\"Fluid.Container.DisableJoinSignalWait\") !== true, // readClientsWaitForJoinSignal\n\t\tinputs,\n\t\tdeltaManager,\n\t\tclientId,\n\t);\n}\n\nexport function createConnectionStateHandlerCore(\n\tconnectedRaisedWhenCaughtUp: boolean,\n\treadClientsWaitForJoinSignal: boolean,\n\tinputs: IConnectionStateHandlerInputs,\n\tdeltaManager: IDeltaManager<unknown, unknown>,\n\tclientId?: string,\n): ConnectionStateCatchup | ConnectionStateHandler {\n\tconst factory = (handler: IConnectionStateHandlerInputs): ConnectionStateHandler =>\n\t\tnew ConnectionStateHandler(handler, readClientsWaitForJoinSignal, clientId);\n\n\treturn connectedRaisedWhenCaughtUp\n\t\t? new ConnectionStateCatchup(inputs, factory, deltaManager)\n\t\t: factory(inputs);\n}\n\n/**\n * Helper internal interface to abstract away Audience & Quorum\n */\ninterface IMembership {\n\ton(\n\t\teventName: \"addMember\" | \"removeMember\",\n\t\tlistener: (clientId: string, details: IClient | ISequencedClient) => void,\n\t);\n\tgetMember(clientId: string): undefined | unknown;\n}\n\n/**\n * Class that can be used as a base class for building IConnectionStateHandler adapters / pipeline.\n * It implements both ends of communication interfaces and passes data back and forward\n */\nclass ConnectionStateHandlerPassThrough\n\timplements IConnectionStateHandler, IConnectionStateHandlerInputs\n{\n\tprotected readonly pimpl: IConnectionStateHandler;\n\n\tconstructor(\n\t\tprotected readonly inputs: IConnectionStateHandlerInputs,\n\t\tpimplFactory: (handler: IConnectionStateHandlerInputs) => IConnectionStateHandler,\n\t) {\n\t\tthis.pimpl = pimplFactory(this);\n\t}\n\n\t// #region IConnectionStateHandler\n\n\tpublic get connectionState(): ConnectionState {\n\t\treturn this.pimpl.connectionState;\n\t}\n\tpublic get pendingClientId(): string | undefined {\n\t\treturn this.pimpl.pendingClientId;\n\t}\n\tpublic get clientId(): string | undefined {\n\t\treturn this.pimpl.clientId;\n\t}\n\n\tpublic containerSaved(): void {\n\t\treturn this.pimpl.containerSaved();\n\t}\n\tpublic dispose(): void {\n\t\treturn this.pimpl.dispose();\n\t}\n\tpublic initProtocol(protocol: IProtocolHandler): void {\n\t\treturn this.pimpl.initProtocol(protocol);\n\t}\n\tpublic receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>): void {\n\t\treturn this.pimpl.receivedDisconnectEvent(reason);\n\t}\n\n\tpublic establishingConnection(reason: IConnectionStateChangeReason): void {\n\t\treturn this.pimpl.establishingConnection(reason);\n\t}\n\n\tpublic cancelEstablishingConnection(reason: IConnectionStateChangeReason): void {\n\t\treturn this.pimpl.cancelEstablishingConnection(reason);\n\t}\n\n\tpublic receivedConnectEvent(details: IConnectionDetailsInternal): void {\n\t\treturn this.pimpl.receivedConnectEvent(details);\n\t}\n\n\t// #endregion\n\n\t// #region IConnectionStateHandlerInputs\n\n\tpublic get logger(): ITelemetryLoggerExt {\n\t\treturn this.inputs.logger;\n\t}\n\tpublic get mc(): MonitoringContext {\n\t\treturn this.inputs.mc;\n\t}\n\tpublic connectionStateChanged(\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason,\n\t): void {\n\t\treturn this.inputs.connectionStateChanged(value, oldState, reason);\n\t}\n\tpublic shouldClientJoinWrite(): boolean {\n\t\treturn this.inputs.shouldClientJoinWrite();\n\t}\n\tpublic get maxClientLeaveWaitTime(): number | undefined {\n\t\treturn this.inputs.maxClientLeaveWaitTime;\n\t}\n\tpublic logConnectionIssue(\n\t\teventName: string,\n\t\tcategory: TelemetryEventCategory,\n\t\tdetails?: ITelemetryBaseProperties,\n\t): void {\n\t\treturn this.inputs.logConnectionIssue(eventName, category, details);\n\t}\n\tpublic clientShouldHaveLeft(clientId: string): void {\n\t\treturn this.inputs.clientShouldHaveLeft(clientId);\n\t}\n\n\tpublic onCriticalError(error: unknown): void {\n\t\treturn this.inputs.onCriticalError(error);\n\t}\n\n\t// #endregion\n}\n\n/**\n * Implementation of IConnectionStateHandler pass-through adapter that waits for specific sequence number\n * before raising connected event\n */\nexport class ConnectionStateCatchup extends ConnectionStateHandlerPassThrough {\n\tprivate catchUpMonitor: ICatchUpMonitor | undefined;\n\n\tconstructor(\n\t\tinputs: IConnectionStateHandlerInputs,\n\t\tpimplFactory: (handler: IConnectionStateHandlerInputs) => IConnectionStateHandler,\n\t\tprivate readonly deltaManager: IDeltaManager<unknown, unknown>,\n\t) {\n\t\tsuper(inputs, pimplFactory);\n\t\tthis._connectionState = this.pimpl.connectionState;\n\t}\n\n\tprivate _connectionState: ConnectionState;\n\tpublic get connectionState(): ConnectionState {\n\t\treturn this._connectionState;\n\t}\n\n\tpublic connectionStateChanged(\n\t\tvalue: ConnectionState,\n\t\toldState: ConnectionState,\n\t\treason?: IConnectionStateChangeReason<IAnyDriverError>,\n\t): void {\n\t\tswitch (value) {\n\t\t\tcase ConnectionState.Connected: {\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.CatchingUp,\n\t\t\t\t\t0x3e1 /* connectivity transitions */,\n\t\t\t\t);\n\t\t\t\t// Create catch-up monitor here (not earlier), as we might get more exact info by now about how far\n\t\t\t\t// client is behind through join signal. This is only true if base layer uses signals (i.e. audience,\n\t\t\t\t// not quorum, including for \"rea\" connections) to make decisions about moving to \"connected\" state.\n\t\t\t\t// In addition to that, in its current form, doing this in ConnectionState.CatchingUp is dangerous as\n\t\t\t\t// we might get callback right away, and it will screw up state transition (as code outside of switch\n\t\t\t\t// statement will overwrite current state).\n\t\t\t\tassert(this.catchUpMonitor === undefined, 0x3eb /* catchUpMonitor should be gone */);\n\t\t\t\tthis.catchUpMonitor = new CatchUpMonitor(\n\t\t\t\t\tthis.deltaManager,\n\t\t\t\t\tthis.transitionToConnectedState,\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase ConnectionState.Disconnected: {\n\t\t\t\tthis.catchUpMonitor?.dispose();\n\t\t\t\tthis.catchUpMonitor = undefined;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t// ConnectionState.EstablishingConnection state would be set when we start establishing connection\n\t\t\t// during container.connect() or reconnect because of an error.\n\t\t\tcase ConnectionState.EstablishingConnection: {\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.Disconnected,\n\t\t\t\t\t0x6d2 /* connectivity transition to establishing connection */,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase ConnectionState.CatchingUp: {\n\t\t\t\tassert(\n\t\t\t\t\tthis._connectionState === ConnectionState.EstablishingConnection,\n\t\t\t\t\t0x3e3 /* connectivity transitions */,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t}\n\t\tthis._connectionState = value;\n\t\tthis.inputs.connectionStateChanged(value, oldState, reason);\n\t}\n\n\tprivate readonly transitionToConnectedState = (): void => {\n\t\t// Defensive measure, we should always be in Connecting state when this is called.\n\t\tconst state = this.pimpl.connectionState;\n\t\tassert(state === ConnectionState.Connected, 0x3e5 /* invariant broken */);\n\t\tassert(this._connectionState === ConnectionState.CatchingUp, 0x3e6 /* invariant broken */);\n\t\tthis._connectionState = ConnectionState.Connected;\n\t\tthis.inputs.connectionStateChanged(ConnectionState.Connected, ConnectionState.CatchingUp, {\n\t\t\ttext: \"caught up\",\n\t\t});\n\t};\n}\n\n/**\n * In the lifetime of a container, the connection will likely disconnect and reconnect periodically.\n * This class ensures that any ops sent by this container instance on previous connection are either\n * sequenced or blocked by the server before emitting the new \"connected\" event and allowing runtime to resubmit ops.\n *\n * Each connection is assigned a clientId by the service, and the connection is book-ended by a Join and a Leave op\n * generated by the service. Due to the distributed nature of the Relay Service, in the case of reconnect we cannot\n * make any assumptions about ordering of operations between the old and new connections - i.e. new Join op could\n * be sequenced before old Leave op (and some acks from pending ops that were in flight when we disconnected).\n *\n * The job of this class is to encapsulate the transition period during reconnect, which is identified by\n * ConnectionState.CatchingUp. Specifically, before moving to Connected state with the new clientId, it ensures that:\n *\n * a. We process the Leave op for the previous clientId. This allows us to properly handle any acks from in-flight ops\n * that got sequenced with the old clientId (we'll recognize them as local ops). After the Leave op, any other\n * pending ops can safely be submitted with the new clientId without fear of duplication in the sequenced op stream.\n *\n * b. We process the Join op for the new clientId (identified when the underlying connection was first established),\n * indicating the service is ready to sequence ops sent with the new clientId.\n *\n * c. We process all ops known at the time the underlying connection was established (so we are \"caught up\")\n *\n * For (a) we give up waiting after some time (same timeout as server uses), and go ahead and transition to Connected.\n *\n * For (b) we log telemetry if it takes too long, but still only transition to Connected when the Join op/signal is\n * processed.\n *\n * For (c) this is optional behavior, controlled by the parameters of receivedConnectEvent\n */\nexport class ConnectionStateHandler implements IConnectionStateHandler {\n\tprivate _connectionState = ConnectionState.Disconnected;\n\tprivate _pendingClientId: string | undefined;\n\n\t/**\n\t * Tracks that we observe the \"leave\" op within the timeout for our previous clientId (see comment on ConnectionStateHandler class)\n\t * ! This ensures we do not switch to a new clientId until we process all potential messages from old clientId\n\t * ! i.e. We will always see the \"leave\" op for a client after we have seen all the ops it has sent\n\t * ! This check helps prevent the same op from being resubmitted by the PendingStateManager upon reconnecting\n\t */\n\tprivate readonly prevClientLeftTimer: Timer;\n\n\t/**\n\t * Tracks that we observe our own \"join\" op within the timeout after receiving a \"connected\" event from the DeltaManager\n\t */\n\tprivate readonly joinTimer: Timer;\n\n\tprivate protocol?: IProtocolHandler;\n\tprivate connection?: IConnectionDetailsInternal;\n\tprivate _clientId?: string;\n\n\t/**\n\t * Track how long we waited to see \"leave\" op for previous clientId\n\t */\n\tprivate waitEvent: PerformanceEvent | undefined;\n\n\tpublic get connectionState(): ConnectionState {\n\t\treturn this._connectionState;\n\t}\n\n\tpublic get clientId(): string | undefined {\n\t\treturn this._clientId;\n\t}\n\n\tpublic get pendingClientId(): string | undefined {\n\t\treturn this._pendingClientId;\n\t}\n\n\tconstructor(\n\t\tprivate readonly handler: IConnectionStateHandlerInputs,\n\t\tprivate readonly readClientsWaitForJoinSignal: boolean,\n\t\tclientIdFromPausedSession?: string,\n\t) {\n\t\tthis._clientId = clientIdFromPausedSession;\n\t\t// eslint-disable-next-line unicorn/consistent-function-scoping\n\t\tconst errorHandler = (error): void => this.handler.onCriticalError(error);\n\t\tthis.prevClientLeftTimer = new Timer(\n\t\t\t// Default is 5 min for which we are going to wait for its own \"leave\" message. This is same as\n\t\t\t// the max time on server after which leave op is sent.\n\t\t\tthis.handler.maxClientLeaveWaitTime ?? 300000,\n\t\t\t() => {\n\t\t\t\tassert(\n\t\t\t\t\tthis.connectionState !== ConnectionState.Connected,\n\t\t\t\t\t0x2ac /* \"Connected when timeout waiting for leave from previous session fired!\" */,\n\t\t\t\t);\n\t\t\t\tthis.applyForConnectedState(\"timeout\");\n\t\t\t},\n\t\t\terrorHandler,\n\t\t);\n\n\t\tthis.joinTimer = new Timer(\n\t\t\t0, // default value is not used - startjoinTimer() explicitly provides timeout\n\t\t\t() => {\n\t\t\t\t// I've observed timer firing within couple ms from disconnect event, looks like\n\t\t\t\t// queued timer callback is not cancelled if timer is cancelled while callback sits in the queue.\n\t\t\t\tif (this.connectionState !== ConnectionState.CatchingUp) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst details = {\n\t\t\t\t\tprotocolInitialized: this.protocol !== undefined,\n\t\t\t\t\tpendingClientId: this.pendingClientId,\n\t\t\t\t\tclientJoined: this.hasMember(this.pendingClientId),\n\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t};\n\t\t\t\tthis.handler.logConnectionIssue(\n\t\t\t\t\tthis.connection?.mode === \"read\" ? \"NoJoinSignal\" : \"NoJoinOp\", // eventName\n\t\t\t\t\t\"error\", // category\n\t\t\t\t\tdetails,\n\t\t\t\t);\n\t\t\t},\n\t\t\terrorHandler,\n\t\t);\n\t}\n\n\tprivate startjoinTimer(): void {\n\t\tassert(!this.joinTimer.hasTimer, 0x234 /* \"has joinTimer\" */);\n\t\tassert(this.connection !== undefined, 0x4b3 /* have connection */);\n\t\tthis.joinTimer.start(\n\t\t\tthis.connection.mode === \"write\" ? JoinOpTimeoutMs : JoinSignalTimeoutMs,\n\t\t);\n\t}\n\n\tprivate stopjoinTimer(): void {\n\t\tassert(this.joinTimer.hasTimer, 0x235 /* \"no joinTimer\" */);\n\t\tthis.joinTimer.clear();\n\t}\n\n\tprivate get waitingForLeaveOp(): boolean {\n\t\treturn this.prevClientLeftTimer.hasTimer;\n\t}\n\n\tpublic dispose(): void {\n\t\tassert(!this.joinTimer.hasTimer, 0x2a5 /* \"join timer\" */);\n\t\tthis.prevClientLeftTimer.clear();\n\t}\n\n\tpublic containerSaved(): void {\n\t\t// If we were waiting for moving to Connected state, then only apply for state change. Since the container\n\t\t// is now saved and we don't have any ops to roundtrip, we can clear the timer and apply for connected state.\n\t\tif (this.waitingForLeaveOp) {\n\t\t\tthis.prevClientLeftTimer.clear();\n\t\t\tthis.applyForConnectedState(\"containerSaved\");\n\t\t}\n\t}\n\n\tprivate receivedAddMemberEvent(clientId: string): void {\n\t\t// This is the only one that requires the pending client ID\n\t\tif (clientId === this.pendingClientId) {\n\t\t\tif (this.joinTimer.hasTimer) {\n\t\t\t\tthis.stopjoinTimer();\n\t\t\t} else if (this.shouldWaitForSelf()) {\n\t\t\t\t// timer has already fired, meaning it took too long to get join op/signal.\n\t\t\t\t// Record how long it actually took to recover.\n\t\t\t\t// This is generic event, as it by itself is not an error.\n\t\t\t\t// We also have a case where NoJoinOp happens during container boot (we do not report it as error in such case),\n\t\t\t\t// if this log statement happens after boot - we do not want to consider it error case.\n\t\t\t\tthis.handler.logConnectionIssue(\n\t\t\t\t\tthis.connection?.mode === \"read\" ? \"ReceivedJoinSignal\" : \"ReceivedJoinOp\", // eventName\n\t\t\t\t\t\"generic\", // category\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Start the event in case we are waiting for leave or timeout.\n\t\t\tif (this.waitingForLeaveOp) {\n\t\t\t\tthis.waitEvent = PerformanceEvent.start(this.handler.logger, {\n\t\t\t\t\teventName: \"WaitBeforeClientLeave\",\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\twaitOnClientId: this._clientId,\n\t\t\t\t\t\thadOutstandingOps: this.handler.shouldClientJoinWrite(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.applyForConnectedState(\"addMemberEvent\");\n\t\t}\n\t}\n\n\tprivate applyForConnectedState(\n\t\tsource: \"removeMemberEvent\" | \"addMemberEvent\" | \"timeout\" | \"containerSaved\",\n\t): void {\n\t\tassert(\n\t\t\tthis.protocol !== undefined,\n\t\t\t0x236 /* \"In all cases it should be already installed\" */,\n\t\t);\n\n\t\tassert(\n\t\t\t!this.waitingForLeaveOp || this.hasMember(this.clientId),\n\t\t\t0x2e2 /* \"Must only wait for leave message when clientId in quorum\" */,\n\t\t);\n\n\t\t// Move to connected state only if:\n\t\t// 1. We have seen our own \"join\" op (i.e. for this.pendingClientId)\n\t\t// 2. There is no \"leave\" timer running, meaning this is our first connection or the previous client has left (via this.prevClientLeftTimer)\n\t\tif (\n\t\t\tthis.pendingClientId !== this.clientId &&\n\t\t\tthis.hasMember(this.pendingClientId) &&\n\t\t\t!this.waitingForLeaveOp\n\t\t) {\n\t\t\tthis.waitEvent?.end({ source });\n\t\t\tthis.setConnectionState(ConnectionState.Connected);\n\t\t} else {\n\t\t\t// Adding this event temporarily so that we can get help debugging if something goes wrong.\n\t\t\t// We may not see any ops due to being disconnected all that time - that's not an error!\n\t\t\tconst error =\n\t\t\t\tsource === \"timeout\" && this.connectionState !== ConnectionState.Disconnected;\n\t\t\tthis.handler.logger.sendTelemetryEvent({\n\t\t\t\teventName: \"connectedStateRejected\",\n\t\t\t\tcategory: error ? \"error\" : \"generic\",\n\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\tsource,\n\t\t\t\t\tpendingClientId: this.pendingClientId,\n\t\t\t\t\tclientId: this.clientId,\n\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t\tclientJoined: this.hasMember(this.pendingClientId),\n\t\t\t\t}),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate receivedRemoveMemberEvent(clientId: string): void {\n\t\t// If the client which has left was us, then finish the timer.\n\t\tif (this.clientId === clientId && this.waitingForLeaveOp) {\n\t\t\tthis.prevClientLeftTimer.clear();\n\t\t\tthis.applyForConnectedState(\"removeMemberEvent\");\n\t\t}\n\t}\n\n\tpublic receivedDisconnectEvent(reason: IConnectionStateChangeReason<IAnyDriverError>): void {\n\t\tthis.connection = undefined;\n\t\tthis.setConnectionState(ConnectionState.Disconnected, reason);\n\t}\n\n\tpublic cancelEstablishingConnection(reason: IConnectionStateChangeReason): void {\n\t\tassert(\n\t\t\tthis._connectionState === ConnectionState.EstablishingConnection,\n\t\t\t0x6d3 /* Connection state should be EstablishingConnection */,\n\t\t);\n\t\tassert(this.connection === undefined, 0x6d4 /* No connection should be present */);\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.Disconnected;\n\t\tthis.handler.connectionStateChanged(ConnectionState.Disconnected, oldState, reason);\n\t}\n\n\tpublic establishingConnection(reason: IConnectionStateChangeReason): void {\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.EstablishingConnection;\n\t\tthis.handler.connectionStateChanged(ConnectionState.EstablishingConnection, oldState, {\n\t\t\ttext: `Establishing Connection due to ${reason.text}`,\n\t\t\terror: reason.error,\n\t\t});\n\t}\n\n\t/**\n\t * Tells if need to wait for \"self\" to show up in audience.\n\t * @returns - true if we should wait for \"self\" to appear in audience.\n\t * false is returned only for \"read\" connections, and only if this.readClientsWaitForJoinSignal is false.\n\t */\n\tprivate shouldWaitForSelf(): boolean {\n\t\tassert(\n\t\t\tthis.connection !== undefined,\n\t\t\t0x4b4 /* all callers call here with active connection */,\n\t\t);\n\t\treturn this.connection.mode === \"write\" || this.readClientsWaitForJoinSignal;\n\t}\n\n\t/**\n\t * The \"connect\" event indicates the connection to the Relay Service is live.\n\t * However, some additional conditions must be met before we can fully transition to\n\t * \"Connected\" state. This function handles that interim period, known as \"Connecting\" state.\n\t * @param details - Connection details returned from the Relay Service\n\t * @param deltaManager - DeltaManager to be used for delaying Connected transition until caught up.\n\t * If it's undefined, then don't delay and transition to Connected as soon as Leave/Join op are accounted for\n\t */\n\tpublic receivedConnectEvent(details: IConnectionDetailsInternal): void {\n\t\tthis.connection = details;\n\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = ConnectionState.CatchingUp;\n\n\t\t// The following checks are wrong. They are only valid if user has write access to a file.\n\t\t// If user lost such access mid-session, user will not be able to get \"write\" connection.\n\t\t//\n\t\t// const writeConnection = details.mode === \"write\";\n\t\t// assert(!this.handler.shouldClientJoinWrite() || writeConnection,\n\t\t// 0x30a /* shouldClientJoinWrite should imply this is a writeConnection */);\n\t\t// assert(!this.waitingForLeaveOp || writeConnection,\n\t\t// 0x2a6 /* \"waitingForLeaveOp should imply writeConnection (we need to be ready to flush pending ops)\" */);\n\n\t\t// Stash the clientID to detect when transitioning from connecting (socket.io channel open) to connected\n\t\t// (have received the join message for the client ID)\n\t\t// This is especially important in the reconnect case. It's possible there could be outstanding\n\t\t// ops sent by this client, so we should keep the old client id until we see our own client's\n\t\t// join message. after we see the join message for our new connection with our new client id,\n\t\t// we know there can no longer be outstanding ops that we sent with the previous client id.\n\t\tthis._pendingClientId = details.clientId;\n\n\t\t// IMPORTANT: Report telemetry after we set _pendingClientId, but before transitioning to Connected state\n\t\tthis.handler.connectionStateChanged(ConnectionState.CatchingUp, oldState, details.reason);\n\n\t\t// Check if we need to wait for join op/signal, and if we need to wait for leave op from previous connection.\n\t\t// Pending clientId could have joined already (i.e. join op/signal already processed):\n\t\t// We are fetching ops from storage in parallel to connecting to Relay Service,\n\t\t// and given async processes, it's possible that we have already processed our own join message before\n\t\t// connection was fully established.\n\t\tif (!this.hasMember(this._pendingClientId) && this.shouldWaitForSelf()) {\n\t\t\t// We are waiting for our own join op / signal. When it is processed\n\t\t\t// we'll attempt to transition to Connected state via receivedAddMemberEvent() flow.\n\t\t\tthis.startjoinTimer();\n\t\t} else if (!this.waitingForLeaveOp) {\n\t\t\t// We're not waiting for Join or Leave op (if read-only connection those don't even apply),\n\t\t\t// go ahead and declare the state to be Connected!\n\t\t\t// If we are waiting for Leave op still, do nothing for now, we will transition to Connected later.\n\t\t\tthis.setConnectionState(ConnectionState.Connected);\n\t\t}\n\t\t// else - We are waiting for Leave op still, do nothing for now, we will transition to Connected later\n\t}\n\n\tprivate setConnectionState(\n\t\tvalue: ConnectionState.Disconnected,\n\t\treason: IConnectionStateChangeReason,\n\t): void;\n\tprivate setConnectionState(value: ConnectionState.Connected): void;\n\tprivate setConnectionState(\n\t\tvalue: ConnectionState.Disconnected | ConnectionState.Connected,\n\t\treason?: IConnectionStateChangeReason,\n\t): void {\n\t\tif (this.connectionState === value) {\n\t\t\t// Already in the desired state - exit early\n\t\t\tthis.handler.logger.sendErrorEvent({ eventName: \"setConnectionStateSame\", value });\n\t\t\treturn;\n\t\t}\n\n\t\tconst oldState = this._connectionState;\n\t\tthis._connectionState = value;\n\n\t\t// This is the only place in code that deals with quorum. The rest works with audience\n\t\t// The code below ensures that we do not send ops until we know that old \"write\" client's disconnect\n\t\t// produced (and sequenced) leave op\n\t\tconst currentClientInQuorum =\n\t\t\tthis._clientId !== undefined &&\n\t\t\tthis.protocol?.quorum?.getMember(this._clientId) !== undefined;\n\t\tif (value === ConnectionState.Connected) {\n\t\t\tassert(\n\t\t\t\toldState === ConnectionState.CatchingUp,\n\t\t\t\t0x1d8 /* \"Should only transition from Connecting state\" */,\n\t\t\t);\n\t\t\t// Mark our old client should have left in the quorum if it's still there\n\t\t\tif (currentClientInQuorum) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.handler.clientShouldHaveLeft(this._clientId!);\n\t\t\t}\n\t\t\tthis._clientId = this.pendingClientId;\n\t\t} else if (value === ConnectionState.Disconnected) {\n\t\t\tif (this.joinTimer.hasTimer) {\n\t\t\t\tthis.stopjoinTimer();\n\t\t\t}\n\n\t\t\t// Only wait for \"leave\" message if the connected client exists in the quorum and had some non-acked ops\n\t\t\t// Also check if the timer is not already running as\n\t\t\t// we could receive \"Disconnected\" event multiple times without getting connected and in that case we\n\t\t\t// don't want to reset the timer as we still want to wait on original client which started this timer.\n\t\t\tif (\n\t\t\t\tcurrentClientInQuorum &&\n\t\t\t\tthis.handler.shouldClientJoinWrite() &&\n\t\t\t\t!this.waitingForLeaveOp // same as !this.prevClientLeftTimer.hasTimer\n\t\t\t) {\n\t\t\t\tthis.prevClientLeftTimer.restart();\n\t\t\t} else {\n\t\t\t\t// Adding this event temporarily so that we can get help debugging if something goes wrong.\n\t\t\t\tthis.handler.logger.sendTelemetryEvent({\n\t\t\t\t\teventName: \"noWaitOnDisconnected\",\n\t\t\t\t\tdetails: JSON.stringify({\n\t\t\t\t\t\tclientId: this._clientId,\n\t\t\t\t\t\tinQuorum: currentClientInQuorum,\n\t\t\t\t\t\twaitingForLeaveOp: this.waitingForLeaveOp,\n\t\t\t\t\t\thadOutstandingOps: this.handler.shouldClientJoinWrite(),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Report transition\n\t\tthis.handler.connectionStateChanged(this._connectionState, oldState, reason);\n\n\t\t// Clear pending state immediately to prepare for reconnect\n\t\t// Do it after calling connectionStateChanged() above, such that our telemetry contains pendingClientId on disconnect events\n\t\t// and we can pair attempts to connect with disconnects (that's the only ID we have if connection did not move far enough before being disconnected)\n\t\tif (value === ConnectionState.Disconnected) {\n\t\t\tthis._pendingClientId = undefined;\n\t\t}\n\t}\n\n\tprotected get membership(): IMembership | undefined {\n\t\t// We could always use audience here.\n\t\t// This is true because Audience is a superset of quorum, i.e. when we filter Audience to \"write\" clients,\n\t\t// it is exactly the same as quorum! Please see asserts in Audience callbacks setup by initProtocol() enforcing that.\n\t\treturn this.readClientsWaitForJoinSignal ? this.protocol?.audience : this.protocol?.quorum;\n\t}\n\n\tpublic initProtocol(protocol: IProtocolHandler): void {\n\t\tthis.protocol = protocol;\n\n\t\tthis.membership?.on(\"addMember\", (clientId, details) => {\n\t\t\t// This is very important constrain. We rely on it when testing presence of \"self\" in Audience.\n\t\t\t// We do not want to move to \"connected\" state for \"write\" connections when JoinSignal shows up\n\t\t\t// for \"self\" - we want to move to \"connected\" state only when \"join\" op is received.\n\t\t\tassert(\n\t\t\t\t(details as IClient).mode === \"read\" ||\n\t\t\t\t\tprotocol.quorum.getMember(clientId) !== undefined,\n\t\t\t\t0x4b5 /* Audience is subset of quorum */,\n\t\t\t);\n\t\t\tthis.receivedAddMemberEvent(clientId);\n\t\t});\n\n\t\tthis.membership?.on(\"removeMember\", (clientId) => {\n\t\t\tassert(\n\t\t\t\tprotocol.quorum.getMember(clientId) === undefined,\n\t\t\t\t0x4b6 /* Audience is subset of quorum */,\n\t\t\t);\n\t\t\tthis.receivedRemoveMemberEvent(clientId);\n\t\t});\n\n\t\t/* There is a tiny tiny race possible, where these events happen in this order:\n 1. A connection is established (no \"cached\" mode is used, so it happens in parallel / faster than other steps)\n 2. Some other client produces a summary\n 3. We get \"lucky\" and load from that summary as our initial snapshot\n 4. ConnectionStateHandler.initProtocol is called, \"self\" is already in the quorum.\n We could avoid this sequence (and delete test case for it) if we move connection lower in Container.load()\n */\n\t\tif (this.hasMember(this.pendingClientId)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tthis.receivedAddMemberEvent(this.pendingClientId!);\n\t\t}\n\n\t\tassert(\n\t\t\t!this.waitingForLeaveOp,\n\t\t\t0x99d /* leave timer can't be set as we have not had access to quorum */,\n\t\t);\n\n\t\t// This check is required for scenario of loading container from pending state, and ensuring there is no way\n\t\t// old clientId is still in the quorum (very unlikely, but you never know)\n\t\t// if we have a clientId from a previous container we need to wait for its leave message\n\t\t// This mimicks check in setConnectionState()\n\t\t// Note that we are not consulting this.handler.shouldClientJoinWrite() here\n\t\t// It could produce wrong results for stashed ops were never sent to Loader yet, and if this check\n\t\t// makes determination only on that (and not uses \"dirty\" events), then it can produce wrong result.\n\t\t// In most cases it does not matter, as this client already left quorum. But in really unfortunate case,\n\t\t// we might wait even if we could avoid such wait.\n\t\tif (\n\t\t\tthis._clientId !== undefined &&\n\t\t\tprotocol.quorum?.getMember(this._clientId) !== undefined\n\t\t) {\n\t\t\tthis.prevClientLeftTimer.restart();\n\t\t}\n\t}\n\n\tprotected hasMember(clientId?: string): boolean {\n\t\treturn this.membership?.getMember(clientId ?? \"\") !== undefined;\n\t}\n}\n"]}
@@ -101,6 +101,7 @@ export interface IContainerCreateProps {
101
101
  * but it maybe still behind.
102
102
  *
103
103
  * @throws an error beginning with `"Container closed"` if the container is closed before it catches up.
104
+ * @legacy
104
105
  * @alpha
105
106
  */
106
107
  export declare function waitContainerToCatchUp(container: IContainer): Promise<boolean>;
@@ -170,7 +171,9 @@ export declare class Container extends EventEmitterWithErrorHandling<IContainerE
170
171
  private get runtime();
171
172
  private _protocolHandler;
172
173
  private get protocolHandler();
173
- /** During initialization we pause the inbound queues. We track this state to ensure we only call resume once */
174
+ /**
175
+ * During initialization we pause the inbound queues. We track this state to ensure we only call resume once
176
+ */
174
177
  private inboundQueuePausedFromInit;
175
178
  private firstConnection;
176
179
  private readonly connectionTransitionTimes;
@@ -318,7 +321,9 @@ export declare class Container extends EventEmitterWithErrorHandling<IContainerE
318
321
  private logConnectionStateChangeTelemetry;
319
322
  private propagateConnectionState;
320
323
  private submitContainerMessage;
321
- /** @returns clientSequenceNumber of last message in a batch */
324
+ /**
325
+ * Gets the `clientSequenceNumber` of last message in a batch.
326
+ */
322
327
  private submitBatch;
323
328
  private submitSummaryMessage;
324
329
  private submitMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
package/dist/container.js CHANGED
@@ -8,6 +8,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
8
8
  };
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.Container = exports.ReportIfTooLong = exports.waitContainerToCatchUp = void 0;
11
+ /* eslint-disable unicorn/consistent-function-scoping */
11
12
  const client_utils_1 = require("@fluid-internal/client-utils");
12
13
  const container_definitions_1 = require("@fluidframework/container-definitions");
13
14
  const internal_1 = require("@fluidframework/container-definitions/internal");
@@ -56,6 +57,7 @@ const packageNotFactoryError = "Code package does not implement IRuntimeFactory"
56
57
  * but it maybe still behind.
57
58
  *
58
59
  * @throws an error beginning with `"Container closed"` if the container is closed before it catches up.
60
+ * @legacy
59
61
  * @alpha
60
62
  */
61
63
  async function waitContainerToCatchUp(container) {
@@ -68,9 +70,9 @@ async function waitContainerToCatchUp(container) {
68
70
  const closedCallback = (err) => {
69
71
  container.off("closed", closedCallback);
70
72
  const baseMessage = "Container closed while waiting to catch up";
71
- reject(err !== undefined
72
- ? (0, internal_5.wrapError)(err, (innerMessage) => new internal_5.GenericError(`${baseMessage}: ${innerMessage}`))
73
- : new internal_5.GenericError(baseMessage));
73
+ reject(err === undefined
74
+ ? new internal_5.GenericError(baseMessage)
75
+ : (0, internal_5.wrapError)(err, (innerMessage) => new internal_5.GenericError(`${baseMessage}: ${innerMessage}`)));
74
76
  };
75
77
  container.on("closed", closedCallback);
76
78
  // Depending on config, transition to "connected" state may include the guarantee
@@ -396,7 +398,9 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
396
398
  * disposed: Container has been disposed
397
399
  */
398
400
  this._lifecycleState = "loading";
399
- /** During initialization we pause the inbound queues. We track this state to ensure we only call resume once */
401
+ /**
402
+ * During initialization we pause the inbound queues. We track this state to ensure we only call resume once
403
+ */
400
404
  this.inboundQueuePausedFromInit = true;
401
405
  this.firstConnection = true;
402
406
  this.connectionTransitionTimes = [];
@@ -648,7 +652,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
648
652
  const offlineLoadEnabled = (this.isInteractiveClient &&
649
653
  this.mc.config.getBoolean("Fluid.Container.enableOfflineLoad")) ??
650
654
  options.enableOfflineLoad === true;
651
- this.serializedStateManager = new serializedStateManager_js_1.SerializedStateManager(pendingLocalState, this.subLogger, this.storageAdapter, offlineLoadEnabled, this, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi());
655
+ this.serializedStateManager = new serializedStateManager_js_1.SerializedStateManager(pendingLocalState, this.subLogger, this.storageAdapter, offlineLoadEnabled, this, () => this._deltaManager.connectionManager.shouldJoinWrite(), () => this.supportGetSnapshotApi(), this.mc.config.getNumber("Fluid.Container.snapshotRefreshTimeoutMs"));
652
656
  const isDomAvailable = typeof document === "object" &&
653
657
  document !== null &&
654
658
  typeof document.addEventListener === "function" &&
@@ -713,8 +717,8 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
713
717
  this._protocolHandler?.close();
714
718
  this.connectionStateHandler.dispose();
715
719
  }
716
- catch (exception) {
717
- this.mc.logger.sendErrorEvent({ eventName: "ContainerCloseException" }, exception);
720
+ catch (newError) {
721
+ this.mc.logger.sendErrorEvent({ eventName: "ContainerCloseException" }, newError);
718
722
  }
719
723
  this.emit("closed", error);
720
724
  if (this.visibilityEventHandler !== undefined) {
@@ -748,7 +752,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
748
752
  }
749
753
  this._protocolHandler?.close();
750
754
  this.connectionStateHandler.dispose();
751
- const maybeError = error !== undefined ? new Error(error.message) : undefined;
755
+ const maybeError = error === undefined ? undefined : new Error(error.message);
752
756
  this._runtime?.dispose(maybeError);
753
757
  this.storageAdapter.dispose();
754
758
  // Notify storage about critical errors. They may be due to disconnect between client & server knowledge
@@ -756,8 +760,8 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
756
760
  // Driver need to ensure all caches are cleared on critical errors
757
761
  this.service?.dispose(error);
758
762
  }
759
- catch (exception) {
760
- this.mc.logger.sendErrorEvent({ eventName: "ContainerDisposeException" }, exception);
763
+ catch (error_) {
764
+ this.mc.logger.sendErrorEvent({ eventName: "ContainerDisposeException" }, error_);
761
765
  }
762
766
  this.emit("disposed", error);
763
767
  this.removeAllListeners();
@@ -815,7 +819,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
815
819
  const combinedSummary = attachingData?.summary ??
816
820
  (0, utils_js_1.combineAppAndProtocolSummary)(this.runtime.createSummary(), this.captureProtocolSummary());
817
821
  const { baseSnapshot, snapshotBlobs } = (0, utils_js_1.getSnapshotTreeAndBlobsFromSerializedContainer)(combinedSummary);
818
- const pendingRuntimeState = attachingData !== undefined ? this.runtime.getPendingLocalState() : undefined;
822
+ const pendingRuntimeState = attachingData === undefined ? undefined : this.runtime.getPendingLocalState();
819
823
  (0, internal_2.assert)(!(0, internal_2.isPromiseLike)(pendingRuntimeState), 0x8e3 /* should not be a promise */);
820
824
  const detachedContainerState = {
821
825
  attached: false,
@@ -1015,17 +1019,20 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1015
1019
  // Attach op handlers to finish initialization and be able to start processing ops
1016
1020
  // Kick off any ops fetching if required.
1017
1021
  switch (loadMode.opsBeforeReturn) {
1018
- case undefined:
1022
+ case undefined: {
1019
1023
  // Start prefetch, but not set opsBeforeReturnP - boot is not blocked by it!
1020
1024
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
1021
- this.attachDeltaManagerOpHandler(attributes, loadMode.deltaConnection !== "none" ? "all" : "none", lastProcessedSequenceNumber);
1025
+ this.attachDeltaManagerOpHandler(attributes, loadMode.deltaConnection === "none" ? "none" : "all", lastProcessedSequenceNumber);
1022
1026
  break;
1027
+ }
1023
1028
  case "cached":
1024
- case "all":
1029
+ case "all": {
1025
1030
  opsBeforeReturnP = this.attachDeltaManagerOpHandler(attributes, loadMode.opsBeforeReturn, lastProcessedSequenceNumber);
1026
1031
  break;
1027
- default:
1032
+ }
1033
+ default: {
1028
1034
  (0, internal_2.unreachableCase)(loadMode.opsBeforeReturn);
1035
+ }
1029
1036
  }
1030
1037
  // ...load in the existing quorum
1031
1038
  // Initialize the protocol handler
@@ -1147,7 +1154,9 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1147
1154
  this.initializeProtocolState(attributes, quorumSnapshot);
1148
1155
  }
1149
1156
  initializeProtocolState(attributes, quorumSnapshot) {
1150
- const protocol = this.protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) => this.submitMessage(internal_3.MessageType.Propose, JSON.stringify({ key, value })));
1157
+ const protocol = this.protocolHandlerBuilder(attributes, quorumSnapshot, (key, value) =>
1158
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1159
+ this.submitMessage(internal_3.MessageType.Propose, JSON.stringify({ key, value })));
1151
1160
  const protocolLogger = (0, internal_5.createChildLogger)({
1152
1161
  logger: this.subLogger,
1153
1162
  namespace: "ProtocolHandler",
@@ -1211,9 +1220,8 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1211
1220
  return pkg;
1212
1221
  }
1213
1222
  static setupClient(containerId, loaderOptionsClient, clientDetailsOverride) {
1214
- const client = loaderOptionsClient !== undefined
1215
- ? (0, structured_clone_1.default)(loaderOptionsClient)
1216
- : {
1223
+ const client = loaderOptionsClient === undefined
1224
+ ? {
1217
1225
  details: {
1218
1226
  capabilities: { interactive: true },
1219
1227
  },
@@ -1221,7 +1229,8 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1221
1229
  permission: [],
1222
1230
  scopes: [],
1223
1231
  user: { id: "" },
1224
- };
1232
+ }
1233
+ : (0, structured_clone_1.default)(loaderOptionsClient);
1225
1234
  if (clientDetailsOverride !== undefined) {
1226
1235
  client.details = {
1227
1236
  ...client.details,
@@ -1364,7 +1373,7 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1364
1373
  autoReconnect,
1365
1374
  opsBehind,
1366
1375
  online: internal_4.OnlineStatus[(0, internal_4.isOnline)()],
1367
- lastVisible: this.lastVisible !== undefined ? client_utils_1.performance.now() - this.lastVisible : undefined,
1376
+ lastVisible: this.lastVisible === undefined ? undefined : client_utils_1.performance.now() - this.lastVisible,
1368
1377
  checkpointSequenceNumber,
1369
1378
  quorumSize: this._protocolHandler?.quorum.getMembers().size,
1370
1379
  isDirty: this.isDirty,
@@ -1395,10 +1404,12 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1395
1404
  // back-compat: ADO #1385: Remove in the future, summary op should come through submitSummaryMessage()
1396
1405
  submitContainerMessage(type, contents, batch, metadata) {
1397
1406
  switch (type) {
1398
- case internal_3.MessageType.Operation:
1407
+ case internal_3.MessageType.Operation: {
1399
1408
  return this.submitMessage(type, JSON.stringify(contents), batch, metadata);
1400
- case internal_3.MessageType.Summarize:
1409
+ }
1410
+ case internal_3.MessageType.Summarize: {
1401
1411
  return this.submitSummaryMessage(contents);
1412
+ }
1402
1413
  default: {
1403
1414
  const newError = new internal_5.GenericError("invalidContainerSubmitOpType", undefined /* error */, { messageType: type });
1404
1415
  this.close(newError);
@@ -1406,7 +1417,9 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1406
1417
  }
1407
1418
  }
1408
1419
  }
1409
- /** @returns clientSequenceNumber of last message in a batch */
1420
+ /**
1421
+ * Gets the `clientSequenceNumber` of last message in a batch.
1422
+ */
1410
1423
  submitBatch(batch, referenceSequenceNumber) {
1411
1424
  let clientSequenceNumber = -1;
1412
1425
  for (const message of batch) {
@@ -1532,22 +1545,26 @@ class Container extends internal_5.EventEmitterWithErrorHandling {
1532
1545
  // and runtime implementation may miss such events.
1533
1546
  (0, internal_2.assert)(this.loaded, 0x96f /* has to be called after container transitions to loaded state */);
1534
1547
  switch (deltaConnectionArg) {
1535
- case undefined:
1548
+ case undefined: {
1536
1549
  if (connectionArgs) {
1537
1550
  // connect to delta stream now since we did not before
1538
1551
  this.connectToDeltaStream(connectionArgs);
1539
1552
  }
1553
+ }
1540
1554
  // intentional fallthrough
1541
- case "delayed":
1555
+ case "delayed": {
1542
1556
  (0, internal_2.assert)(this.inboundQueuePausedFromInit, 0x346 /* inboundQueuePausedFromInit should be true */);
1543
1557
  this.inboundQueuePausedFromInit = false;
1544
1558
  this._deltaManager.inbound.resume();
1545
1559
  this._deltaManager.inboundSignal.resume();
1546
1560
  break;
1547
- case "none":
1561
+ }
1562
+ case "none": {
1548
1563
  break;
1549
- default:
1564
+ }
1565
+ default: {
1550
1566
  (0, internal_2.unreachableCase)(deltaConnectionArg);
1567
+ }
1551
1568
  }
1552
1569
  }
1553
1570
  }