@fluidframework/container-runtime 2.0.0-dev.6.4.0.192049 → 2.0.0-dev.7.2.0.204906

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 (345) hide show
  1. package/CHANGELOG.md +119 -0
  2. package/api-extractor.json +1 -1
  3. package/api-report/container-runtime.api.md +866 -0
  4. package/dist/blobManager.d.ts +4 -6
  5. package/dist/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager.js +56 -78
  7. package/dist/blobManager.js.map +1 -1
  8. package/dist/connectionTelemetry.d.ts.map +1 -1
  9. package/dist/connectionTelemetry.js +75 -42
  10. package/dist/connectionTelemetry.js.map +1 -1
  11. package/dist/container-runtime-alpha.d.ts +1744 -0
  12. package/dist/container-runtime-beta.d.ts +1744 -0
  13. package/dist/container-runtime-public.d.ts +1744 -0
  14. package/dist/container-runtime-untrimmed.d.ts +1805 -0
  15. package/dist/containerHandleContext.js +3 -3
  16. package/dist/containerHandleContext.js.map +1 -1
  17. package/dist/containerRuntime.d.ts +94 -102
  18. package/dist/containerRuntime.d.ts.map +1 -1
  19. package/dist/containerRuntime.js +478 -454
  20. package/dist/containerRuntime.js.map +1 -1
  21. package/dist/dataStore.js +11 -11
  22. package/dist/dataStore.js.map +1 -1
  23. package/dist/dataStoreContext.d.ts +2 -4
  24. package/dist/dataStoreContext.d.ts.map +1 -1
  25. package/dist/dataStoreContext.js +56 -59
  26. package/dist/dataStoreContext.js.map +1 -1
  27. package/dist/dataStoreRegistry.d.ts +3 -0
  28. package/dist/dataStoreRegistry.d.ts.map +1 -1
  29. package/dist/dataStoreRegistry.js +6 -3
  30. package/dist/dataStoreRegistry.js.map +1 -1
  31. package/dist/dataStores.d.ts +0 -2
  32. package/dist/dataStores.d.ts.map +1 -1
  33. package/dist/dataStores.js +3 -8
  34. package/dist/dataStores.js.map +1 -1
  35. package/dist/deltaManagerProxyBase.js +4 -4
  36. package/dist/deltaManagerProxyBase.js.map +1 -1
  37. package/dist/deltaManagerSummarizerProxy.js +6 -6
  38. package/dist/deltaManagerSummarizerProxy.js.map +1 -1
  39. package/dist/deltaScheduler.js.map +1 -1
  40. package/dist/error.d.ts.map +1 -1
  41. package/dist/error.js.map +1 -1
  42. package/dist/gc/garbageCollection.d.ts +6 -0
  43. package/dist/gc/garbageCollection.d.ts.map +1 -1
  44. package/dist/gc/garbageCollection.js +36 -25
  45. package/dist/gc/garbageCollection.js.map +1 -1
  46. package/dist/gc/gcConfigs.d.ts +1 -0
  47. package/dist/gc/gcConfigs.d.ts.map +1 -1
  48. package/dist/gc/gcConfigs.js +13 -3
  49. package/dist/gc/gcConfigs.js.map +1 -1
  50. package/dist/gc/gcDefinitions.d.ts +48 -28
  51. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  52. package/dist/gc/gcDefinitions.js +10 -7
  53. package/dist/gc/gcDefinitions.js.map +1 -1
  54. package/dist/gc/gcSummaryDefinitions.d.ts +1 -1
  55. package/dist/gc/gcSummaryDefinitions.js.map +1 -1
  56. package/dist/gc/gcTelemetry.d.ts +3 -4
  57. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  58. package/dist/gc/gcTelemetry.js +7 -8
  59. package/dist/gc/gcTelemetry.js.map +1 -1
  60. package/dist/gc/gcUnreferencedStateTracker.js +3 -3
  61. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  62. package/dist/gc/index.d.ts +2 -2
  63. package/dist/gc/index.d.ts.map +1 -1
  64. package/dist/gc/index.js +3 -7
  65. package/dist/gc/index.js.map +1 -1
  66. package/dist/id-compressor/appendOnlySortedMap.js.map +1 -1
  67. package/dist/id-compressor/idCompressor.js.map +1 -1
  68. package/dist/id-compressor/identifiers.d.ts +3 -3
  69. package/dist/id-compressor/identifiers.d.ts.map +1 -1
  70. package/dist/id-compressor/utilities.d.ts +3 -0
  71. package/dist/id-compressor/utilities.d.ts.map +1 -1
  72. package/dist/id-compressor/utilities.js +3 -0
  73. package/dist/id-compressor/utilities.js.map +1 -1
  74. package/dist/index.d.ts +5 -3
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +6 -2
  77. package/dist/index.js.map +1 -1
  78. package/dist/messageTypes.d.ts +137 -0
  79. package/dist/messageTypes.d.ts.map +1 -0
  80. package/dist/messageTypes.js +32 -0
  81. package/dist/messageTypes.js.map +1 -0
  82. package/dist/opLifecycle/batchManager.js +6 -6
  83. package/dist/opLifecycle/batchManager.js.map +1 -1
  84. package/dist/opLifecycle/definitions.d.ts +7 -3
  85. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  86. package/dist/opLifecycle/definitions.js.map +1 -1
  87. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  88. package/dist/opLifecycle/opDecompressor.js +0 -4
  89. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  90. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  91. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  92. package/dist/opLifecycle/opSplitter.js +3 -3
  93. package/dist/opLifecycle/opSplitter.js.map +1 -1
  94. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  95. package/dist/opLifecycle/outbox.js +7 -2
  96. package/dist/opLifecycle/outbox.js.map +1 -1
  97. package/dist/opLifecycle/remoteMessageProcessor.d.ts +17 -3
  98. package/dist/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  99. package/dist/opLifecycle/remoteMessageProcessor.js +38 -25
  100. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  101. package/dist/packageVersion.d.ts +1 -1
  102. package/dist/packageVersion.js +1 -1
  103. package/dist/packageVersion.js.map +1 -1
  104. package/dist/pendingStateManager.d.ts +4 -20
  105. package/dist/pendingStateManager.d.ts.map +1 -1
  106. package/dist/pendingStateManager.js +36 -46
  107. package/dist/pendingStateManager.js.map +1 -1
  108. package/dist/scheduleManager.js +6 -2
  109. package/dist/scheduleManager.js.map +1 -1
  110. package/dist/summary/orderedClientElection.d.ts +7 -4
  111. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  112. package/dist/summary/orderedClientElection.js +54 -54
  113. package/dist/summary/orderedClientElection.js.map +1 -1
  114. package/dist/summary/runWhileConnectedCoordinator.d.ts +5 -0
  115. package/dist/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  116. package/dist/summary/runWhileConnectedCoordinator.js +7 -6
  117. package/dist/summary/runWhileConnectedCoordinator.js.map +1 -1
  118. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  119. package/dist/summary/runningSummarizer.js +40 -38
  120. package/dist/summary/runningSummarizer.js.map +1 -1
  121. package/dist/summary/summarizer.d.ts +2 -0
  122. package/dist/summary/summarizer.d.ts.map +1 -1
  123. package/dist/summary/summarizer.js +18 -8
  124. package/dist/summary/summarizer.js.map +1 -1
  125. package/dist/summary/summarizerClientElection.js +6 -6
  126. package/dist/summary/summarizerClientElection.js.map +1 -1
  127. package/dist/summary/summarizerHeuristics.js +9 -9
  128. package/dist/summary/summarizerHeuristics.js.map +1 -1
  129. package/dist/summary/summarizerNode/summarizerNode.d.ts +1 -1
  130. package/dist/summary/summarizerNode/summarizerNode.js +8 -8
  131. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  132. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  133. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  134. package/dist/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  135. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  136. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  137. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  138. package/dist/summary/summarizerTypes.d.ts +107 -22
  139. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  140. package/dist/summary/summarizerTypes.js.map +1 -1
  141. package/dist/summary/summaryCollection.d.ts +18 -2
  142. package/dist/summary/summaryCollection.d.ts.map +1 -1
  143. package/dist/summary/summaryCollection.js +23 -21
  144. package/dist/summary/summaryCollection.js.map +1 -1
  145. package/dist/summary/summaryFormat.d.ts +15 -6
  146. package/dist/summary/summaryFormat.d.ts.map +1 -1
  147. package/dist/summary/summaryFormat.js.map +1 -1
  148. package/dist/summary/summaryGenerator.d.ts +3 -3
  149. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  150. package/dist/summary/summaryGenerator.js.map +1 -1
  151. package/dist/summary/summaryManager.d.ts +2 -2
  152. package/dist/summary/summaryManager.d.ts.map +1 -1
  153. package/dist/summary/summaryManager.js +10 -10
  154. package/dist/summary/summaryManager.js.map +1 -1
  155. package/dist/throttler.js +16 -16
  156. package/dist/throttler.js.map +1 -1
  157. package/dist/tsdoc-metadata.json +1 -1
  158. package/lib/blobManager.d.ts +4 -6
  159. package/lib/blobManager.d.ts.map +1 -1
  160. package/lib/blobManager.js +58 -80
  161. package/lib/blobManager.js.map +1 -1
  162. package/lib/connectionTelemetry.d.ts.map +1 -1
  163. package/lib/connectionTelemetry.js +76 -43
  164. package/lib/connectionTelemetry.js.map +1 -1
  165. package/lib/containerHandleContext.js +3 -3
  166. package/lib/containerHandleContext.js.map +1 -1
  167. package/lib/containerRuntime.d.ts +94 -102
  168. package/lib/containerRuntime.d.ts.map +1 -1
  169. package/lib/containerRuntime.js +437 -418
  170. package/lib/containerRuntime.js.map +1 -1
  171. package/lib/dataStore.js +11 -11
  172. package/lib/dataStore.js.map +1 -1
  173. package/lib/dataStoreContext.d.ts +2 -4
  174. package/lib/dataStoreContext.d.ts.map +1 -1
  175. package/lib/dataStoreContext.js +57 -60
  176. package/lib/dataStoreContext.js.map +1 -1
  177. package/lib/dataStoreRegistry.d.ts +3 -0
  178. package/lib/dataStoreRegistry.d.ts.map +1 -1
  179. package/lib/dataStoreRegistry.js +6 -3
  180. package/lib/dataStoreRegistry.js.map +1 -1
  181. package/lib/dataStores.d.ts +0 -2
  182. package/lib/dataStores.d.ts.map +1 -1
  183. package/lib/dataStores.js +4 -9
  184. package/lib/dataStores.js.map +1 -1
  185. package/lib/deltaManagerProxyBase.js +4 -4
  186. package/lib/deltaManagerProxyBase.js.map +1 -1
  187. package/lib/deltaManagerSummarizerProxy.js +6 -6
  188. package/lib/deltaManagerSummarizerProxy.js.map +1 -1
  189. package/lib/deltaScheduler.js.map +1 -1
  190. package/lib/error.d.ts.map +1 -1
  191. package/lib/error.js.map +1 -1
  192. package/lib/gc/garbageCollection.d.ts +6 -0
  193. package/lib/gc/garbageCollection.d.ts.map +1 -1
  194. package/lib/gc/garbageCollection.js +36 -25
  195. package/lib/gc/garbageCollection.js.map +1 -1
  196. package/lib/gc/gcConfigs.d.ts +1 -0
  197. package/lib/gc/gcConfigs.d.ts.map +1 -1
  198. package/lib/gc/gcConfigs.js +15 -5
  199. package/lib/gc/gcConfigs.js.map +1 -1
  200. package/lib/gc/gcDefinitions.d.ts +48 -28
  201. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  202. package/lib/gc/gcDefinitions.js +9 -6
  203. package/lib/gc/gcDefinitions.js.map +1 -1
  204. package/lib/gc/gcSummaryDefinitions.d.ts +1 -1
  205. package/lib/gc/gcSummaryDefinitions.js.map +1 -1
  206. package/lib/gc/gcTelemetry.d.ts +3 -4
  207. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  208. package/lib/gc/gcTelemetry.js +7 -8
  209. package/lib/gc/gcTelemetry.js.map +1 -1
  210. package/lib/gc/gcUnreferencedStateTracker.js +3 -3
  211. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  212. package/lib/gc/index.d.ts +2 -2
  213. package/lib/gc/index.d.ts.map +1 -1
  214. package/lib/gc/index.js +2 -2
  215. package/lib/gc/index.js.map +1 -1
  216. package/lib/id-compressor/appendOnlySortedMap.js.map +1 -1
  217. package/lib/id-compressor/idCompressor.js.map +1 -1
  218. package/lib/id-compressor/identifiers.d.ts +3 -3
  219. package/lib/id-compressor/identifiers.d.ts.map +1 -1
  220. package/lib/id-compressor/utilities.d.ts +3 -0
  221. package/lib/id-compressor/utilities.d.ts.map +1 -1
  222. package/lib/id-compressor/utilities.js +3 -0
  223. package/lib/id-compressor/utilities.js.map +1 -1
  224. package/lib/index.d.ts +5 -3
  225. package/lib/index.d.ts.map +1 -1
  226. package/lib/index.js +3 -1
  227. package/lib/index.js.map +1 -1
  228. package/lib/messageTypes.d.ts +137 -0
  229. package/lib/messageTypes.d.ts.map +1 -0
  230. package/lib/messageTypes.js +29 -0
  231. package/lib/messageTypes.js.map +1 -0
  232. package/lib/opLifecycle/batchManager.js +6 -6
  233. package/lib/opLifecycle/batchManager.js.map +1 -1
  234. package/lib/opLifecycle/definitions.d.ts +7 -3
  235. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  236. package/lib/opLifecycle/definitions.js.map +1 -1
  237. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  238. package/lib/opLifecycle/opDecompressor.js +0 -4
  239. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  240. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  241. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  242. package/lib/opLifecycle/opSplitter.js +1 -1
  243. package/lib/opLifecycle/opSplitter.js.map +1 -1
  244. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  245. package/lib/opLifecycle/outbox.js +7 -2
  246. package/lib/opLifecycle/outbox.js.map +1 -1
  247. package/lib/opLifecycle/remoteMessageProcessor.d.ts +17 -3
  248. package/lib/opLifecycle/remoteMessageProcessor.d.ts.map +1 -1
  249. package/lib/opLifecycle/remoteMessageProcessor.js +37 -24
  250. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  251. package/lib/packageVersion.d.ts +1 -1
  252. package/lib/packageVersion.js +1 -1
  253. package/lib/packageVersion.js.map +1 -1
  254. package/lib/pendingStateManager.d.ts +4 -20
  255. package/lib/pendingStateManager.d.ts.map +1 -1
  256. package/lib/pendingStateManager.js +35 -45
  257. package/lib/pendingStateManager.js.map +1 -1
  258. package/lib/scheduleManager.js +6 -2
  259. package/lib/scheduleManager.js.map +1 -1
  260. package/lib/summary/orderedClientElection.d.ts +7 -4
  261. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  262. package/lib/summary/orderedClientElection.js +54 -54
  263. package/lib/summary/orderedClientElection.js.map +1 -1
  264. package/lib/summary/runWhileConnectedCoordinator.d.ts +5 -0
  265. package/lib/summary/runWhileConnectedCoordinator.d.ts.map +1 -1
  266. package/lib/summary/runWhileConnectedCoordinator.js +7 -6
  267. package/lib/summary/runWhileConnectedCoordinator.js.map +1 -1
  268. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  269. package/lib/summary/runningSummarizer.js +40 -38
  270. package/lib/summary/runningSummarizer.js.map +1 -1
  271. package/lib/summary/summarizer.d.ts +2 -0
  272. package/lib/summary/summarizer.d.ts.map +1 -1
  273. package/lib/summary/summarizer.js +19 -9
  274. package/lib/summary/summarizer.js.map +1 -1
  275. package/lib/summary/summarizerClientElection.js +6 -6
  276. package/lib/summary/summarizerClientElection.js.map +1 -1
  277. package/lib/summary/summarizerHeuristics.js +9 -9
  278. package/lib/summary/summarizerHeuristics.js.map +1 -1
  279. package/lib/summary/summarizerNode/summarizerNode.d.ts +1 -1
  280. package/lib/summary/summarizerNode/summarizerNode.js +8 -8
  281. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  282. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts +1 -1
  283. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  284. package/lib/summary/summarizerNode/summarizerNodeUtils.js +3 -3
  285. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  286. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts +2 -2
  287. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  288. package/lib/summary/summarizerTypes.d.ts +107 -22
  289. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  290. package/lib/summary/summarizerTypes.js.map +1 -1
  291. package/lib/summary/summaryCollection.d.ts +18 -2
  292. package/lib/summary/summaryCollection.d.ts.map +1 -1
  293. package/lib/summary/summaryCollection.js +23 -21
  294. package/lib/summary/summaryCollection.js.map +1 -1
  295. package/lib/summary/summaryFormat.d.ts +15 -6
  296. package/lib/summary/summaryFormat.d.ts.map +1 -1
  297. package/lib/summary/summaryFormat.js.map +1 -1
  298. package/lib/summary/summaryGenerator.d.ts +3 -3
  299. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  300. package/lib/summary/summaryGenerator.js.map +1 -1
  301. package/lib/summary/summaryManager.d.ts +2 -2
  302. package/lib/summary/summaryManager.d.ts.map +1 -1
  303. package/lib/summary/summaryManager.js +9 -9
  304. package/lib/summary/summaryManager.js.map +1 -1
  305. package/lib/throttler.js +16 -16
  306. package/lib/throttler.js.map +1 -1
  307. package/package.json +32 -29
  308. package/src/blobManager.ts +67 -92
  309. package/src/connectionTelemetry.ts +97 -52
  310. package/src/containerRuntime.ts +351 -351
  311. package/src/dataStore.ts +3 -3
  312. package/src/dataStoreContext.ts +9 -13
  313. package/src/dataStoreRegistry.ts +3 -0
  314. package/src/dataStores.ts +5 -17
  315. package/src/error.ts +4 -1
  316. package/src/gc/garbageCollection.ts +25 -12
  317. package/src/gc/gcConfigs.ts +25 -7
  318. package/src/gc/gcDefinitions.ts +49 -29
  319. package/src/gc/gcSummaryDefinitions.ts +1 -1
  320. package/src/gc/gcTelemetry.ts +8 -8
  321. package/src/gc/index.ts +2 -6
  322. package/src/id-compressor/utilities.ts +3 -0
  323. package/src/index.ts +21 -5
  324. package/src/messageTypes.ts +228 -0
  325. package/src/opLifecycle/README.md +93 -68
  326. package/src/opLifecycle/definitions.ts +5 -1
  327. package/src/opLifecycle/opDecompressor.ts +0 -8
  328. package/src/opLifecycle/opGroupingManager.ts +2 -4
  329. package/src/opLifecycle/opSplitter.ts +2 -2
  330. package/src/opLifecycle/outbox.ts +3 -0
  331. package/src/opLifecycle/remoteMessageProcessor.ts +54 -33
  332. package/src/packageVersion.ts +1 -1
  333. package/src/pendingStateManager.ts +31 -52
  334. package/src/scheduleManager.ts +2 -0
  335. package/src/summary/orderedClientElection.ts +4 -1
  336. package/src/summary/runWhileConnectedCoordinator.ts +5 -1
  337. package/src/summary/runningSummarizer.ts +3 -1
  338. package/src/summary/summarizer.ts +21 -7
  339. package/src/summary/summarizerNode/summarizerNode.ts +1 -1
  340. package/src/summary/summarizerTypes.ts +96 -11
  341. package/src/summary/summaryCollection.ts +19 -1
  342. package/src/summary/summaryFormat.ts +11 -1
  343. package/src/summary/summaryGenerator.ts +3 -3
  344. package/src/summary/summaryManager.ts +2 -2
  345. package/src/gc/gcEarlyAdoption.md +0 -145
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.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 {\n\tcreateChildMonitoringContext,\n\tGenericError,\n\tMonitoringContext,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IBatchMessage, ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { ICompressionRuntimeOptions } from \"../containerRuntime\";\nimport { IPendingBatchMessage, PendingStateManager } from \"../pendingStateManager\";\nimport {\n\tBatchManager,\n\tBatchSequenceNumbers,\n\testimateSocketSize,\n\tsequenceNumbersMatch,\n} from \"./batchManager\";\nimport { BatchMessage, IBatch } from \"./definitions\";\nimport { OpCompressor } from \"./opCompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t// The maximum size of a batch that we can send over the wire.\n\treadonly maxBatchSizeInBytes: number;\n\treadonly disablePartialFlush: boolean;\n\treadonly enableGroupedBatching: boolean;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly submitBatchFn:\n\t\t| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)\n\t\t| undefined;\n\treadonly legacySendBatchFn: (batch: IBatch) => void;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryBaseLogger;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n\treadonly reSubmit: (message: IPendingBatchMessage) => void;\n\treadonly opReentrancy: () => boolean;\n\treadonly closeContainer: (error?: ICriticalContainerError) => void;\n}\n\n/**\n * Temporarily increase the stack limit while executing the provided action.\n * If a negative value is provided for `length`, no stack frames will be collected.\n * If Infinity is provided, all frames will be collected.\n *\n * ADO:4663 - add this to the common packages.\n *\n * @param action - action which returns an error\n * @param length - number of stack frames to collect, 50 if unspecified.\n * @returns the result of the action provided\n */\nexport function getLongStack<T>(action: () => T, length: number = 50): T {\n\tconst errorObj = Error as any;\n\tif (\n\t\t(\n\t\t\tObject.getOwnPropertyDescriptor(errorObj, \"stackTraceLimit\") ||\n\t\t\tObject.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), \"stackTraceLimit\")\n\t\t)?.writable !== true\n\t) {\n\t\treturn action();\n\t}\n\n\tconst originalStackTraceLimit = errorObj.stackTraceLimit;\n\ttry {\n\t\terrorObj.stackTraceLimit = length;\n\t\treturn action();\n\t} finally {\n\t\terrorObj.stackTraceLimit = originalStackTraceLimit;\n\t}\n}\n\nexport class Outbox {\n\tprivate readonly mc: MonitoringContext;\n\tprivate readonly attachFlowBatch: BatchManager;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly blobAttachBatch: BatchManager;\n\tprivate readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;\n\tprivate batchRebasesToReport = 5;\n\tprivate rebasing = false;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.mc = createChildMonitoringContext({ logger: params.logger, namespace: \"Outbox\" });\n\t\tconst isCompressionEnabled =\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes !==\n\t\t\tNumber.POSITIVE_INFINITY;\n\t\t// We need to allow infinite size batches if we enable compression\n\t\tconst hardLimit = isCompressionEnabled ? Infinity : this.params.config.maxBatchSizeInBytes;\n\t\tconst softLimit = isCompressionEnabled ? Infinity : this.defaultAttachFlowSoftLimitInBytes;\n\n\t\tthis.attachFlowBatch = new BatchManager({ hardLimit, softLimit });\n\t\tthis.mainBatch = new BatchManager({ hardLimit });\n\t\tthis.blobAttachBatch = new BatchManager({ hardLimit });\n\t}\n\n\tpublic get messageCount(): number {\n\t\treturn this.attachFlowBatch.length + this.mainBatch.length + this.blobAttachBatch.length;\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.messageCount === 0;\n\t}\n\n\t/**\n\t * If we detect that the reference sequence number of the incoming message does not match\n\t * what was already in the batch managers, this means that batching has been interrupted so\n\t * we will flush the accumulated messages to account for that and create a new batch with the new\n\t * message as the first message.\n\t */\n\tprivate maybeFlushPartialBatch() {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;\n\t\tconst blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tthis.params.config.disablePartialFlush ||\n\t\t\t\t(sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums) &&\n\t\t\t\t\tsequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums)),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\tcategory: this.params.config.disablePartialFlush ? \"error\" : \"generic\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tattachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tattachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tblobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,\n\t\t\t\t\tblobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,\n\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t},\n\t\t\t\tgetLongStack(() => new UsageError(\"Submission of an out of order message\")),\n\t\t\t);\n\t\t}\n\n\t\tif (!this.params.config.disablePartialFlush) {\n\t\t\tthis.flushAll();\n\t\t}\n\t}\n\n\tpublic submit(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.mainBatch, message);\n\t}\n\n\tpublic submitAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tif (\n\t\t\t!this.attachFlowBatch.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\t// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged\n\t\t\t// when queue is not empty.\n\t\t\t// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\n\t\t\tthis.addMessageToBatchManager(this.attachFlowBatch, message);\n\t\t}\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// attach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.attachFlowBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\t\t}\n\t}\n\n\tpublic submitBlobAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.blobAttachBatch, message);\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// blobAttach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.blobAttachBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.blobAttachBatch);\n\t\t}\n\t}\n\n\tprivate addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {\n\t\tif (\n\t\t\t!batchManager.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\topSize: message.contents?.length ?? 0,\n\t\t\t\tbatchSize: batchManager.contentSizeInBytes,\n\t\t\t\tcount: batchManager.length,\n\t\t\t\tlimit: batchManager.options.hardLimit,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic flush() {\n\t\tif (this.isContextReentrant()) {\n\t\t\tconst error = new UsageError(\"Flushing is not supported inside DDS event handlers\");\n\t\t\tthis.params.closeContainer(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tthis.flushAll();\n\t}\n\n\tprivate flushAll() {\n\t\tthis.flushInternal(this.attachFlowBatch);\n\t\tthis.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);\n\t\tthis.flushInternal(this.mainBatch);\n\t}\n\n\tprivate flushInternal(batchManager: BatchManager, disableGroupedBatching: boolean = false) {\n\t\tif (batchManager.empty) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst rawBatch = batchManager.popBatch();\n\t\tif (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {\n\t\t\tassert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);\n\t\t\t// If a batch contains reentrant ops (ops created as a result from processing another op)\n\t\t\t// it needs to be rebased so that we can ensure consistent reference sequence numbers\n\t\t\t// and eventual consistency at the DDS level.\n\t\t\tthis.rebase(rawBatch, batchManager);\n\t\t\treturn;\n\t\t}\n\n\t\tconst processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);\n\t\tthis.sendBatch(processedBatch);\n\n\t\tthis.persistBatch(rawBatch.content);\n\t}\n\n\t/**\n\t * Rebases a batch. All the ops in the batch are resubmitted to the runtime and\n\t * they will end up back in the same batch manager they were flushed from and subsequently flushed.\n\t *\n\t * @param rawBatch - the batch to be rebased\n\t */\n\tprivate rebase(rawBatch: IBatch, batchManager: BatchManager) {\n\t\tassert(!this.rebasing, 0x6fb /* Reentrancy */);\n\n\t\tthis.rebasing = true;\n\t\tfor (const message of rawBatch.content) {\n\t\t\tthis.params.reSubmit({\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tcontent: message.contents!,\n\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\topMetadata: message.metadata,\n\t\t\t});\n\t\t}\n\n\t\tif (this.batchRebasesToReport > 0) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"BatchRebase\",\n\t\t\t\t\tlength: rawBatch.content.length,\n\t\t\t\t\treferenceSequenceNumber: rawBatch.referenceSequenceNumber,\n\t\t\t\t},\n\t\t\t\tnew UsageError(\"BatchRebase\"),\n\t\t\t);\n\t\t\tthis.batchRebasesToReport--;\n\t\t}\n\n\t\tthis.flushInternal(batchManager);\n\t\tthis.rebasing = false;\n\t}\n\n\tprivate isContextReentrant(): boolean {\n\t\treturn this.params.opReentrancy() && !this.rebasing;\n\t}\n\n\tprivate compressBatch(batch: IBatch, disableGroupedBatching: boolean): IBatch {\n\t\tif (\n\t\t\tbatch.content.length === 0 ||\n\t\t\tthis.params.config.compressionOptions === undefined ||\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tbatch.contentSizeInBytes ||\n\t\t\tthis.params.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress\n\t\t\treturn disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(\n\t\t\tdisableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),\n\t\t);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitFirstBatchMessage(compressedBatch);\n\t\t}\n\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\tbatchSize: batch.contentSizeInBytes,\n\t\t\t\tcompressedBatchSize: compressedBatch.contentSizeInBytes,\n\t\t\t\tcount: compressedBatch.content.length,\n\t\t\t\tlimit: this.params.config.maxBatchSizeInBytes,\n\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t */\n\tprivate sendBatch(batch: IBatch) {\n\t\tconst length = batch.content.length;\n\n\t\t// Did we disconnect in the middle of turn-based batch?\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\tif (length === 0 || !this.params.shouldSend()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"LargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tsizeInBytes: batch.contentSizeInBytes,\n\t\t\t\tsocketSize,\n\t\t\t});\n\t\t}\n\n\t\tif (this.params.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.content[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tthis.params.legacySendBatchFn(batch);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tbatch.referenceSequenceNumber !== undefined,\n\t\t\t\t0x58e /* Batch must not be empty */,\n\t\t\t);\n\t\t\tthis.params.submitBatchFn(\n\t\t\t\tbatch.content.map((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate persistBatch(batch: BatchMessage[]) {\n\t\t// Let the PendingStateManager know that a message was submitted.\n\t\t// In future, need to shift toward keeping batch as a whole!\n\t\tfor (const message of batch) {\n\t\t\tthis.params.pendingStateManager.onSubmitMessage(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tmessage.contents!,\n\t\t\t\tmessage.referenceSequenceNumber,\n\t\t\t\tmessage.localOpMetadata,\n\t\t\t\tmessage.metadata,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic checkpoint() {\n\t\treturn {\n\t\t\tmainBatch: this.mainBatch.checkpoint(),\n\t\t\tattachFlowBatch: this.attachFlowBatch.checkpoint(),\n\t\t\tblobAttachBatch: this.blobAttachBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../src/opLifecycle/outbox.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 {\n\tcreateChildMonitoringContext,\n\tGenericError,\n\tMonitoringContext,\n\tUsageError,\n} from \"@fluidframework/telemetry-utils\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { IBatchMessage, ICriticalContainerError } from \"@fluidframework/container-definitions\";\nimport { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { ICompressionRuntimeOptions } from \"../containerRuntime\";\nimport { IPendingBatchMessage, PendingStateManager } from \"../pendingStateManager\";\nimport {\n\tBatchManager,\n\tBatchSequenceNumbers,\n\testimateSocketSize,\n\tsequenceNumbersMatch,\n} from \"./batchManager\";\nimport { BatchMessage, IBatch } from \"./definitions\";\nimport { OpCompressor } from \"./opCompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport interface IOutboxConfig {\n\treadonly compressionOptions: ICompressionRuntimeOptions;\n\t// The maximum size of a batch that we can send over the wire.\n\treadonly maxBatchSizeInBytes: number;\n\treadonly disablePartialFlush: boolean;\n\treadonly enableGroupedBatching: boolean;\n}\n\nexport interface IOutboxParameters {\n\treadonly shouldSend: () => boolean;\n\treadonly pendingStateManager: PendingStateManager;\n\treadonly submitBatchFn:\n\t\t| ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number)\n\t\t| undefined;\n\treadonly legacySendBatchFn: (batch: IBatch) => void;\n\treadonly config: IOutboxConfig;\n\treadonly compressor: OpCompressor;\n\treadonly splitter: OpSplitter;\n\treadonly logger: ITelemetryBaseLogger;\n\treadonly groupingManager: OpGroupingManager;\n\treadonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;\n\treadonly reSubmit: (message: IPendingBatchMessage) => void;\n\treadonly opReentrancy: () => boolean;\n\treadonly closeContainer: (error?: ICriticalContainerError) => void;\n}\n\n/**\n * Temporarily increase the stack limit while executing the provided action.\n * If a negative value is provided for `length`, no stack frames will be collected.\n * If Infinity is provided, all frames will be collected.\n *\n * ADO:4663 - add this to the common packages.\n *\n * @param action - action which returns an error\n * @param length - number of stack frames to collect, 50 if unspecified.\n * @returns the result of the action provided\n */\nexport function getLongStack<T>(action: () => T, length: number = 50): T {\n\tconst errorObj = Error as any;\n\tif (\n\t\t/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */\n\t\t// ?? is not logically equivalent when the first clause returns false.\n\t\t(\n\t\t\tObject.getOwnPropertyDescriptor(errorObj, \"stackTraceLimit\") ||\n\t\t\tObject.getOwnPropertyDescriptor(Object.getPrototypeOf(errorObj), \"stackTraceLimit\")\n\t\t)?.writable !== true\n\t\t/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */\n\t) {\n\t\treturn action();\n\t}\n\n\tconst originalStackTraceLimit = errorObj.stackTraceLimit;\n\ttry {\n\t\terrorObj.stackTraceLimit = length;\n\t\treturn action();\n\t} finally {\n\t\terrorObj.stackTraceLimit = originalStackTraceLimit;\n\t}\n}\n\nexport class Outbox {\n\tprivate readonly mc: MonitoringContext;\n\tprivate readonly attachFlowBatch: BatchManager;\n\tprivate readonly mainBatch: BatchManager;\n\tprivate readonly blobAttachBatch: BatchManager;\n\tprivate readonly defaultAttachFlowSoftLimitInBytes = 320 * 1024;\n\tprivate batchRebasesToReport = 5;\n\tprivate rebasing = false;\n\n\t/**\n\t * Track the number of ops which were detected to have a mismatched\n\t * reference sequence number, in order to self-throttle the telemetry events.\n\t *\n\t * This should be removed as part of ADO:2322\n\t */\n\tprivate readonly maxMismatchedOpsToReport = 3;\n\tprivate mismatchedOpsReported = 0;\n\n\tconstructor(private readonly params: IOutboxParameters) {\n\t\tthis.mc = createChildMonitoringContext({ logger: params.logger, namespace: \"Outbox\" });\n\t\tconst isCompressionEnabled =\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes !==\n\t\t\tNumber.POSITIVE_INFINITY;\n\t\t// We need to allow infinite size batches if we enable compression\n\t\tconst hardLimit = isCompressionEnabled ? Infinity : this.params.config.maxBatchSizeInBytes;\n\t\tconst softLimit = isCompressionEnabled ? Infinity : this.defaultAttachFlowSoftLimitInBytes;\n\n\t\tthis.attachFlowBatch = new BatchManager({ hardLimit, softLimit });\n\t\tthis.mainBatch = new BatchManager({ hardLimit });\n\t\tthis.blobAttachBatch = new BatchManager({ hardLimit });\n\t}\n\n\tpublic get messageCount(): number {\n\t\treturn this.attachFlowBatch.length + this.mainBatch.length + this.blobAttachBatch.length;\n\t}\n\n\tpublic get isEmpty(): boolean {\n\t\treturn this.messageCount === 0;\n\t}\n\n\t/**\n\t * If we detect that the reference sequence number of the incoming message does not match\n\t * what was already in the batch managers, this means that batching has been interrupted so\n\t * we will flush the accumulated messages to account for that and create a new batch with the new\n\t * message as the first message.\n\t */\n\tprivate maybeFlushPartialBatch() {\n\t\tconst mainBatchSeqNums = this.mainBatch.sequenceNumbers;\n\t\tconst attachFlowBatchSeqNums = this.attachFlowBatch.sequenceNumbers;\n\t\tconst blobAttachSeqNums = this.blobAttachBatch.sequenceNumbers;\n\t\tassert(\n\t\t\tthis.params.config.disablePartialFlush ||\n\t\t\t\t(sequenceNumbersMatch(mainBatchSeqNums, attachFlowBatchSeqNums) &&\n\t\t\t\t\tsequenceNumbersMatch(mainBatchSeqNums, blobAttachSeqNums)),\n\t\t\t0x58d /* Reference sequence numbers from both batches must be in sync */,\n\t\t);\n\n\t\tconst currentSequenceNumbers = this.params.getCurrentSequenceNumbers();\n\n\t\tif (\n\t\t\tsequenceNumbersMatch(mainBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(attachFlowBatchSeqNums, currentSequenceNumbers) &&\n\t\t\tsequenceNumbersMatch(blobAttachSeqNums, currentSequenceNumbers)\n\t\t) {\n\t\t\t// The reference sequence numbers are stable, there is nothing to do\n\t\t\treturn;\n\t\t}\n\n\t\tif (++this.mismatchedOpsReported <= this.maxMismatchedOpsToReport) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\tcategory: this.params.config.disablePartialFlush ? \"error\" : \"generic\",\n\t\t\t\t\teventName: \"ReferenceSequenceNumberMismatch\",\n\t\t\t\t\tmainReferenceSequenceNumber: mainBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tmainClientSequenceNumber: mainBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tattachReferenceSequenceNumber: attachFlowBatchSeqNums.referenceSequenceNumber,\n\t\t\t\t\tattachClientSequenceNumber: attachFlowBatchSeqNums.clientSequenceNumber,\n\t\t\t\t\tblobAttachReferenceSequenceNumber: blobAttachSeqNums.referenceSequenceNumber,\n\t\t\t\t\tblobAttachClientSequenceNumber: blobAttachSeqNums.clientSequenceNumber,\n\t\t\t\t\tcurrentReferenceSequenceNumber: currentSequenceNumbers.referenceSequenceNumber,\n\t\t\t\t\tcurrentClientSequenceNumber: currentSequenceNumbers.clientSequenceNumber,\n\t\t\t\t},\n\t\t\t\tgetLongStack(() => new UsageError(\"Submission of an out of order message\")),\n\t\t\t);\n\t\t}\n\n\t\tif (!this.params.config.disablePartialFlush) {\n\t\t\tthis.flushAll();\n\t\t}\n\t}\n\n\tpublic submit(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.mainBatch, message);\n\t}\n\n\tpublic submitAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tif (\n\t\t\t!this.attachFlowBatch.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\t// BatchManager has two limits - soft limit & hard limit. Soft limit is only engaged\n\t\t\t// when queue is not empty.\n\t\t\t// Flush queue & retry. Failure on retry would mean - single message is bigger than hard limit\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\n\t\t\tthis.addMessageToBatchManager(this.attachFlowBatch, message);\n\t\t}\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// attach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.attachFlowBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.attachFlowBatch);\n\t\t}\n\t}\n\n\tpublic submitBlobAttach(message: BatchMessage) {\n\t\tthis.maybeFlushPartialBatch();\n\n\t\tthis.addMessageToBatchManager(this.blobAttachBatch, message);\n\n\t\t// If compression is enabled, we will always successfully receive\n\t\t// blobAttach ops and compress then send them at the next JS turn, regardless\n\t\t// of the overall size of the accumulated ops in the batch.\n\t\t// However, it is more efficient to flush these ops faster, preferably\n\t\t// after they reach a size which would benefit from compression.\n\t\tif (\n\t\t\tthis.blobAttachBatch.contentSizeInBytes >=\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes\n\t\t) {\n\t\t\tthis.flushInternal(this.blobAttachBatch);\n\t\t}\n\t}\n\n\tprivate addMessageToBatchManager(batchManager: BatchManager, message: BatchMessage) {\n\t\tif (\n\t\t\t!batchManager.push(\n\t\t\t\tmessage,\n\t\t\t\tthis.isContextReentrant(),\n\t\t\t\tthis.params.getCurrentSequenceNumbers().clientSequenceNumber,\n\t\t\t)\n\t\t) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\topSize: message.contents?.length ?? 0,\n\t\t\t\tbatchSize: batchManager.contentSizeInBytes,\n\t\t\t\tcount: batchManager.length,\n\t\t\t\tlimit: batchManager.options.hardLimit,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic flush() {\n\t\tif (this.isContextReentrant()) {\n\t\t\tconst error = new UsageError(\"Flushing is not supported inside DDS event handlers\");\n\t\t\tthis.params.closeContainer(error);\n\t\t\tthrow error;\n\t\t}\n\n\t\tthis.flushAll();\n\t}\n\n\tprivate flushAll() {\n\t\tthis.flushInternal(this.attachFlowBatch);\n\t\tthis.flushInternal(this.blobAttachBatch, true /* disableGroupedBatching */);\n\t\tthis.flushInternal(this.mainBatch);\n\t}\n\n\tprivate flushInternal(batchManager: BatchManager, disableGroupedBatching: boolean = false) {\n\t\tif (batchManager.empty) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst rawBatch = batchManager.popBatch();\n\t\tif (rawBatch.hasReentrantOps === true && this.params.config.enableGroupedBatching) {\n\t\t\tassert(!this.rebasing, 0x6fa /* A rebased batch should never have reentrant ops */);\n\t\t\t// If a batch contains reentrant ops (ops created as a result from processing another op)\n\t\t\t// it needs to be rebased so that we can ensure consistent reference sequence numbers\n\t\t\t// and eventual consistency at the DDS level.\n\t\t\tthis.rebase(rawBatch, batchManager);\n\t\t\treturn;\n\t\t}\n\n\t\tconst processedBatch = this.compressBatch(rawBatch, disableGroupedBatching);\n\t\tthis.sendBatch(processedBatch);\n\n\t\tthis.persistBatch(rawBatch.content);\n\t}\n\n\t/**\n\t * Rebases a batch. All the ops in the batch are resubmitted to the runtime and\n\t * they will end up back in the same batch manager they were flushed from and subsequently flushed.\n\t *\n\t * @param rawBatch - the batch to be rebased\n\t */\n\tprivate rebase(rawBatch: IBatch, batchManager: BatchManager) {\n\t\tassert(!this.rebasing, 0x6fb /* Reentrancy */);\n\n\t\tthis.rebasing = true;\n\t\tfor (const message of rawBatch.content) {\n\t\t\tthis.params.reSubmit({\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tcontent: message.contents!,\n\t\t\t\tlocalOpMetadata: message.localOpMetadata,\n\t\t\t\topMetadata: message.metadata,\n\t\t\t});\n\t\t}\n\n\t\tif (this.batchRebasesToReport > 0) {\n\t\t\tthis.mc.logger.sendTelemetryEvent(\n\t\t\t\t{\n\t\t\t\t\teventName: \"BatchRebase\",\n\t\t\t\t\tlength: rawBatch.content.length,\n\t\t\t\t\treferenceSequenceNumber: rawBatch.referenceSequenceNumber,\n\t\t\t\t},\n\t\t\t\tnew UsageError(\"BatchRebase\"),\n\t\t\t);\n\t\t\tthis.batchRebasesToReport--;\n\t\t}\n\n\t\tthis.flushInternal(batchManager);\n\t\tthis.rebasing = false;\n\t}\n\n\tprivate isContextReentrant(): boolean {\n\t\treturn this.params.opReentrancy() && !this.rebasing;\n\t}\n\n\tprivate compressBatch(batch: IBatch, disableGroupedBatching: boolean): IBatch {\n\t\tif (\n\t\t\tbatch.content.length === 0 ||\n\t\t\tthis.params.config.compressionOptions === undefined ||\n\t\t\tthis.params.config.compressionOptions.minimumBatchSizeInBytes >\n\t\t\t\tbatch.contentSizeInBytes ||\n\t\t\tthis.params.submitBatchFn === undefined\n\t\t) {\n\t\t\t// Nothing to do if the batch is empty or if compression is disabled or not supported, or if we don't need to compress\n\t\t\treturn disableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch);\n\t\t}\n\n\t\tconst compressedBatch = this.params.compressor.compressBatch(\n\t\t\tdisableGroupedBatching ? batch : this.params.groupingManager.groupBatch(batch),\n\t\t);\n\n\t\tif (this.params.splitter.isBatchChunkingEnabled) {\n\t\t\treturn compressedBatch.contentSizeInBytes <= this.params.splitter.chunkSizeInBytes\n\t\t\t\t? compressedBatch\n\t\t\t\t: this.params.splitter.splitFirstBatchMessage(compressedBatch);\n\t\t}\n\n\t\tif (compressedBatch.contentSizeInBytes >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthrow new GenericError(\"BatchTooLarge\", /* error */ undefined, {\n\t\t\t\tbatchSize: batch.contentSizeInBytes,\n\t\t\t\tcompressedBatchSize: compressedBatch.contentSizeInBytes,\n\t\t\t\tcount: compressedBatch.content.length,\n\t\t\t\tlimit: this.params.config.maxBatchSizeInBytes,\n\t\t\t\tchunkingEnabled: this.params.splitter.isBatchChunkingEnabled,\n\t\t\t\tcompressionOptions: JSON.stringify(this.params.config.compressionOptions),\n\t\t\t\tsocketSize: estimateSocketSize(batch),\n\t\t\t});\n\t\t}\n\n\t\treturn compressedBatch;\n\t}\n\n\t/**\n\t * Sends the batch object to the container context to be sent over the wire.\n\t *\n\t * @param batch - batch to be sent\n\t */\n\tprivate sendBatch(batch: IBatch) {\n\t\tconst length = batch.content.length;\n\n\t\t// Did we disconnect in the middle of turn-based batch?\n\t\t// If so, do nothing, as pending state manager will resubmit it correctly on reconnect.\n\t\tif (length === 0 || !this.params.shouldSend()) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst socketSize = estimateSocketSize(batch);\n\t\tif (socketSize >= this.params.config.maxBatchSizeInBytes) {\n\t\t\tthis.mc.logger.sendPerformanceEvent({\n\t\t\t\teventName: \"LargeBatch\",\n\t\t\t\tlength: batch.content.length,\n\t\t\t\tsizeInBytes: batch.contentSizeInBytes,\n\t\t\t\tsocketSize,\n\t\t\t});\n\t\t}\n\n\t\tif (this.params.submitBatchFn === undefined) {\n\t\t\t// Legacy path - supporting old loader versions. Can be removed only when LTS moves above\n\t\t\t// version that has support for batches (submitBatchFn)\n\t\t\tassert(\n\t\t\t\tbatch.content[0].compression === undefined,\n\t\t\t\t0x5a6 /* Compression should not have happened if the loader does not support it */,\n\t\t\t);\n\n\t\t\tthis.params.legacySendBatchFn(batch);\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tbatch.referenceSequenceNumber !== undefined,\n\t\t\t\t0x58e /* Batch must not be empty */,\n\t\t\t);\n\t\t\tthis.params.submitBatchFn(\n\t\t\t\tbatch.content.map((message) => ({\n\t\t\t\t\tcontents: message.contents,\n\t\t\t\t\tmetadata: message.metadata,\n\t\t\t\t\tcompression: message.compression,\n\t\t\t\t\treferenceSequenceNumber: message.referenceSequenceNumber,\n\t\t\t\t})),\n\t\t\t\tbatch.referenceSequenceNumber,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate persistBatch(batch: BatchMessage[]) {\n\t\t// Let the PendingStateManager know that a message was submitted.\n\t\t// In future, need to shift toward keeping batch as a whole!\n\t\tfor (const message of batch) {\n\t\t\tthis.params.pendingStateManager.onSubmitMessage(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tmessage.contents!,\n\t\t\t\tmessage.referenceSequenceNumber,\n\t\t\t\tmessage.localOpMetadata,\n\t\t\t\tmessage.metadata,\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic checkpoint() {\n\t\treturn {\n\t\t\tmainBatch: this.mainBatch.checkpoint(),\n\t\t\tattachFlowBatch: this.attachFlowBatch.checkpoint(),\n\t\t\tblobAttachBatch: this.blobAttachBatch.checkpoint(),\n\t\t};\n\t}\n}\n"]}
@@ -3,9 +3,16 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
6
+ import { type InboundSequencedContainerRuntimeMessageOrSystemMessage } from "../messageTypes";
6
7
  import { OpDecompressor } from "./opDecompressor";
7
8
  import { OpGroupingManager } from "./opGroupingManager";
8
9
  import { OpSplitter } from "./opSplitter";
10
+ /**
11
+ * Stateful class for processing incoming remote messages as the virtualization measures are unwrapped,
12
+ * potentially across numerous inbound ops.
13
+ *
14
+ * @internal
15
+ */
9
16
  export declare class RemoteMessageProcessor {
10
17
  private readonly opSplitter;
11
18
  private readonly opDecompressor;
@@ -15,10 +22,17 @@ export declare class RemoteMessageProcessor {
15
22
  clearPartialMessagesFor(clientId: string): void;
16
23
  /**
17
24
  * Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire
18
- * @param remoteMessage - A message from another client, likely a chunked/grouped op
19
- * @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message
25
+ * @param remoteMessageCopy - A shallow copy of a message from another client, possibly virtualized
26
+ * (grouped, compressed, and/or chunked).
27
+ * Being a shallow copy, it's considered mutable, meaning no other Container or other parallel procedure
28
+ * depends on this object instance.
29
+ * Note remoteMessageCopy.contents (and other object props) MUST not be modified,
30
+ * but may be overwritten (as is the case with contents).
31
+ * @returns the unchunked, decompressed, ungrouped, unpacked SequencedContainerRuntimeMessages encapsulated in the remote message.
32
+ * For ops that weren't virtualized (e.g. System ops that the ContainerRuntime will ultimately ignore),
33
+ * a singleton array [remoteMessageCopy] is returned
20
34
  */
21
- process(remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage[];
35
+ process(remoteMessageCopy: ISequencedDocumentMessage): InboundSequencedContainerRuntimeMessageOrSystemMessage[];
22
36
  }
23
37
  /**
24
38
  * Unpacks runtime messages.
@@ -1 +1 @@
1
- {"version":3,"file":"remoteMessageProcessor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAM9F,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,qBAAa,sBAAsB;IAEjC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,iBAAiB;IAGtD,IAAW,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAE1D;IAEM,uBAAuB,CAAC,QAAQ,EAAE,MAAM;IAI/C;;;;OAIG;IACI,OAAO,CAAC,aAAa,EAAE,yBAAyB,GAAG,yBAAyB,EAAE;CAiDrF;AAsCD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAsBhF"}
1
+ {"version":3,"file":"remoteMessageProcessor.d.ts","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,yBAAyB,EAAe,MAAM,sCAAsC,CAAC;AAC9F,OAAO,EAIN,KAAK,sDAAsD,EAE3D,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C;;;;;GAKG;AACH,qBAAa,sBAAsB;IAEjC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAFjB,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,EAAE,iBAAiB;IAGtD,IAAW,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAE1D;IAEM,uBAAuB,CAAC,QAAQ,EAAE,MAAM;IAI/C;;;;;;;;;;;OAWG;IACI,OAAO,CACb,iBAAiB,EAAE,yBAAyB,GAC1C,sDAAsD,EAAE;CAuD3D;AAoCD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAsBhF"}
@@ -3,7 +3,13 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { MessageType } from "@fluidframework/protocol-definitions";
6
- import { ContainerMessageType, } from "../containerRuntime";
6
+ import { ContainerMessageType, } from "../messageTypes";
7
+ /**
8
+ * Stateful class for processing incoming remote messages as the virtualization measures are unwrapped,
9
+ * potentially across numerous inbound ops.
10
+ *
11
+ * @internal
12
+ */
7
13
  export class RemoteMessageProcessor {
8
14
  constructor(opSplitter, opDecompressor, opGroupingManager) {
9
15
  this.opSplitter = opSplitter;
@@ -18,13 +24,21 @@ export class RemoteMessageProcessor {
18
24
  }
19
25
  /**
20
26
  * Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire
21
- * @param remoteMessage - A message from another client, likely a chunked/grouped op
22
- * @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message
27
+ * @param remoteMessageCopy - A shallow copy of a message from another client, possibly virtualized
28
+ * (grouped, compressed, and/or chunked).
29
+ * Being a shallow copy, it's considered mutable, meaning no other Container or other parallel procedure
30
+ * depends on this object instance.
31
+ * Note remoteMessageCopy.contents (and other object props) MUST not be modified,
32
+ * but may be overwritten (as is the case with contents).
33
+ * @returns the unchunked, decompressed, ungrouped, unpacked SequencedContainerRuntimeMessages encapsulated in the remote message.
34
+ * For ops that weren't virtualized (e.g. System ops that the ContainerRuntime will ultimately ignore),
35
+ * a singleton array [remoteMessageCopy] is returned
23
36
  */
24
- process(remoteMessage) {
37
+ process(remoteMessageCopy) {
25
38
  const result = [];
39
+ ensureContentsDeserialized(remoteMessageCopy);
26
40
  // Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)
27
- for (const ungroupedMessage of this.opGroupingManager.ungroupOp(copy(remoteMessage))) {
41
+ for (const ungroupedMessage of this.opGroupingManager.ungroupOp(remoteMessageCopy)) {
28
42
  const message = this.opDecompressor.processMessage(ungroupedMessage).message;
29
43
  for (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {
30
44
  // unpack and unchunk the ungrouped message in place
@@ -57,34 +71,33 @@ export class RemoteMessageProcessor {
57
71
  return result;
58
72
  }
59
73
  }
60
- const copy = (remoteMessage) => {
61
- // Do shallow copy of message, as the processing flow will modify it.
62
- // There might be multiple container instances receiving same message
63
- // We do not need to make deep copy, as each layer will just replace message.content itself,
64
- // but would not modify contents details
65
- const message = { ...remoteMessage };
74
+ /** Takes an incoming message and if the contents is a string, JSON.parse's it in place */
75
+ function ensureContentsDeserialized(mutableMessage) {
66
76
  // back-compat: ADO #1385: eventually should become unconditional, but only for runtime messages!
67
77
  // System message may have no contents, or in some cases (mostly for back-compat) they may have actual objects.
68
78
  // Old ops may contain empty string (I assume noops).
69
- if (typeof message.contents === "string" && message.contents !== "") {
70
- message.contents = JSON.parse(message.contents);
79
+ if (typeof mutableMessage.contents === "string" && mutableMessage.contents !== "") {
80
+ mutableMessage.contents = JSON.parse(mutableMessage.contents);
71
81
  }
72
- return message;
73
- };
82
+ }
74
83
  /**
75
- * For a given message, it moves the nested ContainerRuntimeMessage props one level up.
84
+ * For a given message, it moves the nested InboundContainerRuntimeMessage props one level up.
76
85
  *
77
86
  * The return type illustrates the assumption that the message param
78
- * becomes a ContainerRuntimeMessage by the time the function returns
79
- * (but there is no runtime validation of the 'type' or 'compatDetails' values)
87
+ * becomes a InboundSequencedContainerRuntimeMessage by the time the function returns
88
+ * (but there is no runtime validation of the 'type' or 'compatDetails' values).
80
89
  */
81
90
  function unpack(message) {
82
- const innerContents = message.contents;
83
- // We're going to turn message into a SequencedContainerRuntimeMessage in-place
84
- const sequencedContainerRuntimeMessage = message;
85
- sequencedContainerRuntimeMessage.type = innerContents.type;
86
- sequencedContainerRuntimeMessage.contents = innerContents.contents;
87
- sequencedContainerRuntimeMessage.compatDetails = innerContents.compatDetails;
91
+ // We assume the contents is an InboundContainerRuntimeMessage (the message is "packed")
92
+ const contents = message.contents;
93
+ // We're going to unpack message in-place (promoting those properties of contents up to message itself)
94
+ const messageUnpacked = message;
95
+ messageUnpacked.type = contents.type;
96
+ messageUnpacked.contents = contents.contents;
97
+ if ("compatDetails" in contents) {
98
+ messageUnpacked.compatDetails =
99
+ contents.compatDetails;
100
+ }
88
101
  }
89
102
  /**
90
103
  * Unpacks runtime messages.
@@ -1 +1 @@
1
- {"version":3,"file":"remoteMessageProcessor.js","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.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 { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tContainerMessageType,\n\tContainerRuntimeMessage,\n\tSequencedContainerRuntimeMessage,\n} from \"../containerRuntime\";\nimport { OpDecompressor } from \"./opDecompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\nexport class RemoteMessageProcessor {\n\tconstructor(\n\t\tprivate readonly opSplitter: OpSplitter,\n\t\tprivate readonly opDecompressor: OpDecompressor,\n\t\tprivate readonly opGroupingManager: OpGroupingManager,\n\t) {}\n\n\tpublic get partialMessages(): ReadonlyMap<string, string[]> {\n\t\treturn this.opSplitter.chunks;\n\t}\n\n\tpublic clearPartialMessagesFor(clientId: string) {\n\t\tthis.opSplitter.clearPartialChunks(clientId);\n\t}\n\n\t/**\n\t * Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire\n\t * @param remoteMessage - A message from another client, likely a chunked/grouped op\n\t * @returns the ungrouped, unchunked, unpacked SequencedContainerRuntimeMessage encapsulated in the remote message\n\t */\n\tpublic process(remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage[] {\n\t\tconst result: ISequencedDocumentMessage[] = [];\n\n\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\tfor (const ungroupedMessage of this.opGroupingManager.ungroupOp(copy(remoteMessage))) {\n\t\t\tconst message = this.opDecompressor.processMessage(ungroupedMessage).message;\n\n\t\t\tfor (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {\n\t\t\t\t// unpack and unchunk the ungrouped message in place\n\t\t\t\tunpackRuntimeMessage(ungroupedMessage2);\n\t\t\t\tconst chunkProcessingResult =\n\t\t\t\t\tthis.opSplitter.processRemoteMessage(ungroupedMessage2);\n\t\t\t\tungroupedMessage2 = chunkProcessingResult.message;\n\n\t\t\t\tif (chunkProcessingResult.state !== \"Processed\") {\n\t\t\t\t\t// If the message is not chunked or if the splitter is still rebuilding the original message,\n\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\tresult.push(ungroupedMessage2);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\t\t\tfor (const ungroupedMessageAfterChunking of this.opGroupingManager.ungroupOp(\n\t\t\t\t\tungroupedMessage2,\n\t\t\t\t)) {\n\t\t\t\t\tconst decompressionAfterChunking = this.opDecompressor.processMessage(\n\t\t\t\t\t\tungroupedMessageAfterChunking,\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const ungroupedMessageAfterChunking2 of this.opGroupingManager.ungroupOp(\n\t\t\t\t\t\tdecompressionAfterChunking.message,\n\t\t\t\t\t)) {\n\t\t\t\t\t\tif (decompressionAfterChunking.state === \"Skipped\") {\n\t\t\t\t\t\t\t// After chunking, if the original message was not compressed,\n\t\t\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\t\t\tresult.push(ungroupedMessageAfterChunking2);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// The message needs to be unpacked after chunking + decompression\n\t\t\t\t\t\tunpack(ungroupedMessageAfterChunking2);\n\t\t\t\t\t\tresult.push(ungroupedMessageAfterChunking2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\nconst copy = (remoteMessage: ISequencedDocumentMessage): ISequencedDocumentMessage => {\n\t// Do shallow copy of message, as the processing flow will modify it.\n\t// There might be multiple container instances receiving same message\n\t// We do not need to make deep copy, as each layer will just replace message.content itself,\n\t// but would not modify contents details\n\tconst message = { ...remoteMessage };\n\n\t// back-compat: ADO #1385: eventually should become unconditional, but only for runtime messages!\n\t// System message may have no contents, or in some cases (mostly for back-compat) they may have actual objects.\n\t// Old ops may contain empty string (I assume noops).\n\tif (typeof message.contents === \"string\" && message.contents !== \"\") {\n\t\tmessage.contents = JSON.parse(message.contents);\n\t}\n\n\treturn message;\n};\n\n/**\n * For a given message, it moves the nested ContainerRuntimeMessage props one level up.\n *\n * The return type illustrates the assumption that the message param\n * becomes a ContainerRuntimeMessage by the time the function returns\n * (but there is no runtime validation of the 'type' or 'compatDetails' values)\n */\nfunction unpack(\n\tmessage: ISequencedDocumentMessage,\n): asserts message is SequencedContainerRuntimeMessage {\n\tconst innerContents = message.contents as ContainerRuntimeMessage;\n\n\t// We're going to turn message into a SequencedContainerRuntimeMessage in-place\n\tconst sequencedContainerRuntimeMessage = message as SequencedContainerRuntimeMessage;\n\tsequencedContainerRuntimeMessage.type = innerContents.type;\n\tsequencedContainerRuntimeMessage.contents = innerContents.contents;\n\tsequencedContainerRuntimeMessage.compatDetails = innerContents.compatDetails;\n}\n\n/**\n * Unpacks runtime messages.\n *\n * @remarks This API makes no promises regarding backward-compatibility. This is internal API.\n * @param message - message (as it observed in storage / service)\n * @returns whether the given message was unpacked\n *\n * @internal\n */\nexport function unpackRuntimeMessage(message: ISequencedDocumentMessage): boolean {\n\tif (message.type !== MessageType.Operation) {\n\t\t// Legacy format, but it's already \"unpacked\",\n\t\t// i.e. message.type is actually ContainerMessageType.\n\t\t// Or it's non-runtime message.\n\t\t// Nothing to do in such case.\n\t\treturn false;\n\t}\n\n\t// legacy op format?\n\t// TODO: Unsure if this is a real format we should be concerned with. There doesn't appear to be anything prepared to handle the address member.\n\tif (\n\t\t(message.contents as { address?: unknown }).address !== undefined &&\n\t\t(message.contents as { type?: unknown }).type === undefined\n\t) {\n\t\tmessage.type = ContainerMessageType.FluidDataStoreOp;\n\t} else {\n\t\t// new format\n\t\tunpack(message);\n\t}\n\n\treturn true;\n}\n"]}
1
+ {"version":3,"file":"remoteMessageProcessor.js","sourceRoot":"","sources":["../../src/opLifecycle/remoteMessageProcessor.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 { ISequencedDocumentMessage, MessageType } from \"@fluidframework/protocol-definitions\";\nimport {\n\tContainerMessageType,\n\ttype InboundContainerRuntimeMessage,\n\ttype InboundSequencedContainerRuntimeMessage,\n\ttype InboundSequencedContainerRuntimeMessageOrSystemMessage,\n\ttype InboundSequencedRecentlyAddedContainerRuntimeMessage,\n} from \"../messageTypes\";\nimport { OpDecompressor } from \"./opDecompressor\";\nimport { OpGroupingManager } from \"./opGroupingManager\";\nimport { OpSplitter } from \"./opSplitter\";\n\n/**\n * Stateful class for processing incoming remote messages as the virtualization measures are unwrapped,\n * potentially across numerous inbound ops.\n *\n * @internal\n */\nexport class RemoteMessageProcessor {\n\tconstructor(\n\t\tprivate readonly opSplitter: OpSplitter,\n\t\tprivate readonly opDecompressor: OpDecompressor,\n\t\tprivate readonly opGroupingManager: OpGroupingManager,\n\t) {}\n\n\tpublic get partialMessages(): ReadonlyMap<string, string[]> {\n\t\treturn this.opSplitter.chunks;\n\t}\n\n\tpublic clearPartialMessagesFor(clientId: string) {\n\t\tthis.opSplitter.clearPartialChunks(clientId);\n\t}\n\n\t/**\n\t * Ungroups and Unchunks the runtime ops encapsulated by the single remoteMessage received over the wire\n\t * @param remoteMessageCopy - A shallow copy of a message from another client, possibly virtualized\n\t * (grouped, compressed, and/or chunked).\n\t * Being a shallow copy, it's considered mutable, meaning no other Container or other parallel procedure\n\t * depends on this object instance.\n\t * Note remoteMessageCopy.contents (and other object props) MUST not be modified,\n\t * but may be overwritten (as is the case with contents).\n\t * @returns the unchunked, decompressed, ungrouped, unpacked SequencedContainerRuntimeMessages encapsulated in the remote message.\n\t * For ops that weren't virtualized (e.g. System ops that the ContainerRuntime will ultimately ignore),\n\t * a singleton array [remoteMessageCopy] is returned\n\t */\n\tpublic process(\n\t\tremoteMessageCopy: ISequencedDocumentMessage,\n\t): InboundSequencedContainerRuntimeMessageOrSystemMessage[] {\n\t\tconst result: InboundSequencedContainerRuntimeMessageOrSystemMessage[] = [];\n\n\t\tensureContentsDeserialized(remoteMessageCopy);\n\n\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\tfor (const ungroupedMessage of this.opGroupingManager.ungroupOp(remoteMessageCopy)) {\n\t\t\tconst message = this.opDecompressor.processMessage(ungroupedMessage).message;\n\n\t\t\tfor (let ungroupedMessage2 of this.opGroupingManager.ungroupOp(message)) {\n\t\t\t\t// unpack and unchunk the ungrouped message in place\n\t\t\t\tunpackRuntimeMessage(ungroupedMessage2);\n\t\t\t\tconst chunkProcessingResult =\n\t\t\t\t\tthis.opSplitter.processRemoteMessage(ungroupedMessage2);\n\t\t\t\tungroupedMessage2 = chunkProcessingResult.message;\n\n\t\t\t\tif (chunkProcessingResult.state !== \"Processed\") {\n\t\t\t\t\t// If the message is not chunked or if the splitter is still rebuilding the original message,\n\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\tresult.push(\n\t\t\t\t\t\tungroupedMessage2 as InboundSequencedContainerRuntimeMessageOrSystemMessage,\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Ungroup before and after decompression for back-compat (cleanup tracked by AB#4371)\n\t\t\t\tfor (const ungroupedMessageAfterChunking of this.opGroupingManager.ungroupOp(\n\t\t\t\t\tungroupedMessage2,\n\t\t\t\t)) {\n\t\t\t\t\tconst decompressionAfterChunking = this.opDecompressor.processMessage(\n\t\t\t\t\t\tungroupedMessageAfterChunking,\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const ungroupedMessageAfterChunking2 of this.opGroupingManager.ungroupOp(\n\t\t\t\t\t\tdecompressionAfterChunking.message,\n\t\t\t\t\t)) {\n\t\t\t\t\t\tif (decompressionAfterChunking.state === \"Skipped\") {\n\t\t\t\t\t\t\t// After chunking, if the original message was not compressed,\n\t\t\t\t\t\t\t// there is no need to continue processing\n\t\t\t\t\t\t\tresult.push(\n\t\t\t\t\t\t\t\tungroupedMessageAfterChunking2 as InboundSequencedContainerRuntimeMessageOrSystemMessage,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// The message needs to be unpacked after chunking + decompression\n\t\t\t\t\t\tunpack(ungroupedMessageAfterChunking2);\n\t\t\t\t\t\tresult.push(ungroupedMessageAfterChunking2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n}\n\n/** Takes an incoming message and if the contents is a string, JSON.parse's it in place */\nfunction ensureContentsDeserialized(mutableMessage: ISequencedDocumentMessage): void {\n\t// back-compat: ADO #1385: eventually should become unconditional, but only for runtime messages!\n\t// System message may have no contents, or in some cases (mostly for back-compat) they may have actual objects.\n\t// Old ops may contain empty string (I assume noops).\n\tif (typeof mutableMessage.contents === \"string\" && mutableMessage.contents !== \"\") {\n\t\tmutableMessage.contents = JSON.parse(mutableMessage.contents);\n\t}\n}\n\n/**\n * For a given message, it moves the nested InboundContainerRuntimeMessage props one level up.\n *\n * The return type illustrates the assumption that the message param\n * becomes a InboundSequencedContainerRuntimeMessage by the time the function returns\n * (but there is no runtime validation of the 'type' or 'compatDetails' values).\n */\nfunction unpack(\n\tmessage: ISequencedDocumentMessage,\n): asserts message is InboundSequencedContainerRuntimeMessage {\n\t// We assume the contents is an InboundContainerRuntimeMessage (the message is \"packed\")\n\tconst contents = message.contents as InboundContainerRuntimeMessage;\n\n\t// We're going to unpack message in-place (promoting those properties of contents up to message itself)\n\tconst messageUnpacked = message as InboundSequencedContainerRuntimeMessage;\n\n\tmessageUnpacked.type = contents.type;\n\tmessageUnpacked.contents = contents.contents;\n\tif (\"compatDetails\" in contents) {\n\t\t(messageUnpacked as InboundSequencedRecentlyAddedContainerRuntimeMessage).compatDetails =\n\t\t\tcontents.compatDetails;\n\t}\n}\n\n/**\n * Unpacks runtime messages.\n *\n * @remarks This API makes no promises regarding backward-compatibility. This is internal API.\n * @param message - message (as it observed in storage / service)\n * @returns whether the given message was unpacked\n *\n * @internal\n */\nexport function unpackRuntimeMessage(message: ISequencedDocumentMessage): boolean {\n\tif (message.type !== MessageType.Operation) {\n\t\t// Legacy format, but it's already \"unpacked\",\n\t\t// i.e. message.type is actually ContainerMessageType.\n\t\t// Or it's non-runtime message.\n\t\t// Nothing to do in such case.\n\t\treturn false;\n\t}\n\n\t// legacy op format?\n\t// TODO: Unsure if this is a real format we should be concerned with. There doesn't appear to be anything prepared to handle the address member.\n\tif (\n\t\t(message.contents as { address?: unknown }).address !== undefined &&\n\t\t(message.contents as { type?: unknown }).type === undefined\n\t) {\n\t\tmessage.type = ContainerMessageType.FluidDataStoreOp;\n\t} else {\n\t\t// new format\n\t\tunpack(message);\n\t}\n\n\treturn true;\n}\n"]}
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export declare const pkgName = "@fluidframework/container-runtime";
8
- export declare const pkgVersion = "2.0.0-dev.6.4.0.192049";
8
+ export declare const pkgVersion = "2.0.0-dev.7.2.0.204906";
9
9
  //# sourceMappingURL=packageVersion.d.ts.map
@@ -5,5 +5,5 @@
5
5
  * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY
6
6
  */
7
7
  export const pkgName = "@fluidframework/container-runtime";
8
- export const pkgVersion = "2.0.0-dev.6.4.0.192049";
8
+ export const pkgVersion = "2.0.0-dev.7.2.0.204906";
9
9
  //# sourceMappingURL=packageVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-dev.6.4.0.192049\";\n"]}
1
+ {"version":3,"file":"packageVersion.js","sourceRoot":"","sources":["../src/packageVersion.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,mCAAmC,CAAC;AAC3D,MAAM,CAAC,MAAM,UAAU,GAAG,wBAAwB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n *\n * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY\n */\n\nexport const pkgName = \"@fluidframework/container-runtime\";\nexport const pkgVersion = \"2.0.0-dev.7.2.0.204906\";\n"]}
@@ -5,24 +5,12 @@
5
5
  import { IDisposable } from "@fluidframework/core-interfaces";
6
6
  import { ICriticalContainerError } from "@fluidframework/container-definitions";
7
7
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
8
- import { ContainerMessageType, SequencedContainerRuntimeMessage } from "./containerRuntime";
9
- /**
10
- * ! TODO: Remove this interface in "2.0.0-internal.7.0.0" once we only read IPendingMessageNew (AB#4763)
11
- */
12
- export interface IPendingMessageOld {
13
- type: "message";
14
- messageType: ContainerMessageType;
15
- clientSequenceNumber: number;
16
- referenceSequenceNumber: number;
17
- content: any;
18
- localOpMetadata: unknown;
19
- opMetadata: Record<string, unknown> | undefined;
20
- }
8
+ import { InboundSequencedContainerRuntimeMessage } from "./messageTypes";
21
9
  /**
22
10
  * This represents a message that has been submitted and is added to the pending queue when `submit` is called on the
23
11
  * ContainerRuntime. This message has either not been ack'd by the server or has not been submitted to the server yet.
24
12
  */
25
- export interface IPendingMessageNew {
13
+ export interface IPendingMessage {
26
14
  type: "message";
27
15
  clientSequenceNumber: number;
28
16
  referenceSequenceNumber: number;
@@ -30,15 +18,11 @@ export interface IPendingMessageNew {
30
18
  localOpMetadata: unknown;
31
19
  opMetadata: Record<string, unknown> | undefined;
32
20
  }
33
- /**
34
- * ! TODO: Remove this type in "2.0.0-internal.7.0.0" (AB#4763)
35
- */
36
- export declare type IPendingState = IPendingMessageOld | IPendingMessageNew;
37
21
  export interface IPendingLocalState {
38
22
  /**
39
23
  * list of pending states, including ops and batch information
40
24
  */
41
- pendingStates: IPendingState[];
25
+ pendingStates: IPendingMessage[];
42
26
  }
43
27
  export interface IPendingBatchMessage {
44
28
  content: string;
@@ -108,7 +92,7 @@ export declare class PendingStateManager implements IDisposable {
108
92
  * the batch information was preserved for batch messages.
109
93
  * @param message - The message that got ack'd and needs to be processed.
110
94
  */
111
- processPendingLocalMessage(message: SequencedContainerRuntimeMessage): unknown;
95
+ processPendingLocalMessage(message: InboundSequencedContainerRuntimeMessage): unknown;
112
96
  /**
113
97
  * This message could be the first message in batch. If so, set batch state marking the beginning of a batch.
114
98
  * @param message - The message that is being processed.
@@ -1 +1 @@
1
- {"version":3,"file":"pendingStateManager.d.ts","sourceRoot":"","sources":["../src/pendingStateManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pendingStateManager.d.ts","sourceRoot":"","sources":["../src/pendingStateManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAEhF,OAAO,EAAuB,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAE3F,OAAO,EAAwB,uCAAuC,EAAE,MAAM,gBAAgB,CAAC;AAI/F;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,SAAS,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uBAAuB,EAAE,MAAM,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,kBAAkB;IAClC;;OAEG;IACH,aAAa,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACpC,SAAS,IAAI,OAAO,CAAC;IACrB,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC7C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC9C,aAAa,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,IAAI,CAAC;IACnD,kBAAkB,EAAE,MAAM,OAAO,CAAC;CAClC;AAsBD;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,WAAW;IAmErD,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM;IApExB,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAgC;IAEhE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAyB;IAEzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGzB;IAGH,OAAO,CAAC,iBAAiB,CAAkB;IAI3C,OAAO,CAAC,wBAAwB,CAAwC;IAExE,OAAO,CAAC,QAAQ,CAAqB;IAErC;;;OAGG;IACH,IAAW,oBAAoB,IAAI,MAAM,CAExC;IAED;;;OAGG;IACI,kBAAkB,IAAI,OAAO;IAI7B,aAAa,IAAI,kBAAkB,GAAG,SAAS;gBA4BpC,YAAY,EAAE,oBAAoB,EACnD,iBAAiB,EAAE,kBAAkB,GAAG,SAAS,EAChC,MAAM,EAAE,mBAAmB,GAAG,SAAS;IAOzD,IAAW,QAAQ,YAElB;IACD,SAAgB,OAAO,aAAgC;IAEvD;;;;;;OAMG;IACI,eAAe,CACrB,OAAO,EAAE,MAAM,EACf,uBAAuB,EAAE,MAAM,EAC/B,eAAe,EAAE,OAAO,EACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS;IAchD;;;OAGG;IACU,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM;IA4B9C;;;;OAIG;IACI,0BAA0B,CAAC,OAAO,EAAE,uCAAuC,GAAG,OAAO;IAqC5F;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAe9B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAwD5B;;;OAGG;IACI,mBAAmB;CA4F1B"}
@@ -5,8 +5,18 @@
5
5
  import Deque from "double-ended-queue";
6
6
  import { assert, Lazy } from "@fluidframework/core-utils";
7
7
  import { DataProcessingError } from "@fluidframework/telemetry-utils";
8
- import { ContainerMessageType } from "./containerRuntime";
8
+ import { ContainerMessageType } from "./messageTypes";
9
9
  import { pkgVersion } from "./packageVersion";
10
+ function buildPendingMessageContent(
11
+ // AnyComboFromUnion is needed need to gain access to compatDetails that
12
+ // is only defined for some cases.
13
+ message) {
14
+ // IMPORTANT: Order matters here, this must match the order of the properties used
15
+ // when submitting the message.
16
+ const { type, contents, compatDetails } = message;
17
+ // Any properties that are not defined, won't be emitted by stringify.
18
+ return JSON.stringify({ type, contents, compatDetails });
19
+ }
10
20
  /**
11
21
  * PendingStateManager is responsible for maintaining the messages that have not been sent or have not yet been
12
22
  * acknowledged by the server. It also maintains the batch information for both automatically and manually flushed
@@ -17,45 +27,6 @@ import { pkgVersion } from "./packageVersion";
17
27
  * It verifies that all the ops are acked, are received in the right order and batch information is correct.
18
28
  */
19
29
  export class PendingStateManager {
20
- constructor(stateHandler, initialLocalState, logger) {
21
- this.stateHandler = stateHandler;
22
- this.logger = logger;
23
- this.pendingMessages = new Deque();
24
- this.initialMessages = new Deque();
25
- /**
26
- * Sequenced local ops that are saved when stashing since pending ops may depend on them
27
- */
28
- this.savedOps = [];
29
- this.disposeOnce = new Lazy(() => {
30
- this.initialMessages.clear();
31
- this.pendingMessages.clear();
32
- });
33
- // Indicates whether we are processing a batch.
34
- this.isProcessingBatch = false;
35
- this.dispose = () => this.disposeOnce.value;
36
- /**
37
- * Convert old local state format to the new format (IPendingMessageOld to IPendingMessageNew)
38
- * ! TODO: Remove this conversion in "2.0.0-internal.7.0.0" (AB#4763)
39
- */
40
- if (initialLocalState?.pendingStates) {
41
- for (const initialState of initialLocalState.pendingStates) {
42
- let messageContent = initialState.content;
43
- if (initialState.messageType !== undefined &&
44
- typeof initialState.content !== "string") {
45
- // Convert IPendingMessageOld to IPendingMessageNew
46
- messageContent = JSON.stringify({
47
- type: initialState.messageType,
48
- contents: initialState.content,
49
- });
50
- }
51
- // Note: this object may contain "messageType" prop, but it should not be easily accesible due to interface being used
52
- this.initialMessages.push({
53
- ...initialState,
54
- content: messageContent,
55
- });
56
- }
57
- }
58
- }
59
30
  /**
60
31
  * The pending messages count. Includes `pendingMessages` and `initialMessages` to keep in sync with
61
32
  * 'hasPendingMessages'.
@@ -90,6 +61,26 @@ export class PendingStateManager {
90
61
  };
91
62
  }
92
63
  }
64
+ constructor(stateHandler, initialLocalState, logger) {
65
+ this.stateHandler = stateHandler;
66
+ this.logger = logger;
67
+ this.pendingMessages = new Deque();
68
+ this.initialMessages = new Deque();
69
+ /**
70
+ * Sequenced local ops that are saved when stashing since pending ops may depend on them
71
+ */
72
+ this.savedOps = [];
73
+ this.disposeOnce = new Lazy(() => {
74
+ this.initialMessages.clear();
75
+ this.pendingMessages.clear();
76
+ });
77
+ // Indicates whether we are processing a batch.
78
+ this.isProcessingBatch = false;
79
+ this.dispose = () => this.disposeOnce.value;
80
+ if (initialLocalState?.pendingStates) {
81
+ this.initialMessages.push(...initialLocalState.pendingStates);
82
+ }
83
+ }
93
84
  get disposed() {
94
85
  return this.disposeOnce.evaluated;
95
86
  }
@@ -154,10 +145,7 @@ export class PendingStateManager {
154
145
  assert(pendingMessage !== undefined, 0x169 /* "No pending message found for this remote message" */);
155
146
  this.savedOps.push(pendingMessage);
156
147
  this.pendingMessages.shift();
157
- // IMPORTANT: Order matters here, this must match the order of the properties used
158
- // when submitting the message.
159
- const { type, contents, compatDetails } = message;
160
- const messageContent = JSON.stringify({ type, contents, compatDetails });
148
+ const messageContent = buildPendingMessageContent(message);
161
149
  // Stringified content should match
162
150
  if (pendingMessage.content !== messageContent) {
163
151
  this.stateHandler.close(DataProcessingError.create("pending local message content mismatch", "unexpectedAckReceived", message, {
@@ -207,7 +195,9 @@ export class PendingStateManager {
207
195
  this.stateHandler.close(DataProcessingError.create("Pending batch inconsistency", // Formerly known as asserts 0x16f and 0x170
208
196
  "processPendingLocalMessage", message, {
209
197
  runtimeVersion: pkgVersion,
210
- batchClientId: this.pendingBatchBeginMessage.clientId === null
198
+ batchClientId:
199
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
200
+ this.pendingBatchBeginMessage.clientId === null
211
201
  ? "null"
212
202
  : this.pendingBatchBeginMessage.clientId,
213
203
  clientId: this.stateHandler.clientId(),