@fluidframework/container-runtime 2.118.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (326) hide show
  1. package/CHANGELOG.md +68 -4
  2. package/README.md +53 -50
  3. package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
  4. package/api-report/container-runtime.legacy.alpha.api.md +3 -1
  5. package/api-report/container-runtime.legacy.beta.api.md +3 -1
  6. package/container-runtime.test-files.tar +0 -0
  7. package/dist/batchTracker.d.ts.map +1 -1
  8. package/dist/batchTracker.js +5 -1
  9. package/dist/batchTracker.js.map +1 -1
  10. package/dist/blobManager/blobManager.d.ts +1 -1
  11. package/dist/blobManager/blobManager.d.ts.map +1 -1
  12. package/dist/blobManager/blobManager.js +264 -231
  13. package/dist/blobManager/blobManager.js.map +1 -1
  14. package/dist/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  15. package/dist/channelCollection.d.ts.map +1 -1
  16. package/dist/channelCollection.js +70 -58
  17. package/dist/channelCollection.js.map +1 -1
  18. package/dist/connectionTelemetry.js +38 -20
  19. package/dist/connectionTelemetry.js.map +1 -1
  20. package/dist/containerCompatibility.d.ts +3 -3
  21. package/dist/containerCompatibility.d.ts.map +1 -1
  22. package/dist/containerCompatibility.js +36 -45
  23. package/dist/containerCompatibility.js.map +1 -1
  24. package/dist/containerHandleContext.d.ts.map +1 -1
  25. package/dist/containerHandleContext.js +4 -0
  26. package/dist/containerHandleContext.js.map +1 -1
  27. package/dist/containerRuntime.d.ts +4 -4
  28. package/dist/containerRuntime.d.ts.map +1 -1
  29. package/dist/containerRuntime.js +346 -223
  30. package/dist/containerRuntime.js.map +1 -1
  31. package/dist/dataStore.d.ts.map +1 -1
  32. package/dist/dataStore.js +9 -1
  33. package/dist/dataStore.js.map +1 -1
  34. package/dist/dataStoreContext.d.ts.map +1 -1
  35. package/dist/dataStoreContext.js +184 -127
  36. package/dist/dataStoreContext.js.map +1 -1
  37. package/dist/dataStoreContexts.js +43 -42
  38. package/dist/dataStoreContexts.js.map +1 -1
  39. package/dist/dataStoreRegistry.js +1 -0
  40. package/dist/dataStoreRegistry.js.map +1 -1
  41. package/dist/deltaManagerProxies.js +5 -0
  42. package/dist/deltaManagerProxies.js.map +1 -1
  43. package/dist/deltaScheduler.js +104 -99
  44. package/dist/deltaScheduler.js.map +1 -1
  45. package/dist/error.js +2 -1
  46. package/dist/error.js.map +1 -1
  47. package/dist/gc/garbageCollection.js +85 -55
  48. package/dist/gc/garbageCollection.js.map +1 -1
  49. package/dist/gc/gcConfigs.js +2 -3
  50. package/dist/gc/gcConfigs.js.map +1 -1
  51. package/dist/gc/gcHelpers.js +12 -13
  52. package/dist/gc/gcHelpers.js.map +1 -1
  53. package/dist/gc/gcReferenceGraphAlgorithm.js +1 -2
  54. package/dist/gc/gcReferenceGraphAlgorithm.js.map +1 -1
  55. package/dist/gc/gcSummaryStateTracker.js +8 -3
  56. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  57. package/dist/gc/gcTelemetry.js +12 -5
  58. package/dist/gc/gcTelemetry.js.map +1 -1
  59. package/dist/gc/gcUnreferencedStateTracker.js +18 -1
  60. package/dist/gc/gcUnreferencedStateTracker.js.map +1 -1
  61. package/dist/inboundBatchAggregator.js +122 -117
  62. package/dist/inboundBatchAggregator.js.map +1 -1
  63. package/dist/metadata.d.ts.map +1 -1
  64. package/dist/metadata.js +3 -3
  65. package/dist/metadata.js.map +1 -1
  66. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  67. package/dist/opLifecycle/batchManager.js +11 -5
  68. package/dist/opLifecycle/batchManager.js.map +1 -1
  69. package/dist/opLifecycle/duplicateBatchDetector.js +18 -18
  70. package/dist/opLifecycle/duplicateBatchDetector.js.map +1 -1
  71. package/dist/opLifecycle/index.d.ts +2 -2
  72. package/dist/opLifecycle/index.d.ts.map +1 -1
  73. package/dist/opLifecycle/index.js +2 -1
  74. package/dist/opLifecycle/index.js.map +1 -1
  75. package/dist/opLifecycle/opCompressor.js +2 -1
  76. package/dist/opLifecycle/opCompressor.js.map +1 -1
  77. package/dist/opLifecycle/opDecompressor.js +10 -6
  78. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  79. package/dist/opLifecycle/opGroupingManager.js +5 -3
  80. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  81. package/dist/opLifecycle/opSerialization.d.ts +11 -1
  82. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  83. package/dist/opLifecycle/opSerialization.js +22 -6
  84. package/dist/opLifecycle/opSerialization.js.map +1 -1
  85. package/dist/opLifecycle/opSplitter.d.ts +17 -1
  86. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  87. package/dist/opLifecycle/opSplitter.js +46 -9
  88. package/dist/opLifecycle/opSplitter.js.map +1 -1
  89. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  90. package/dist/opLifecycle/outbox.js +17 -13
  91. package/dist/opLifecycle/outbox.js.map +1 -1
  92. package/dist/opLifecycle/remoteMessageProcessor.js +6 -3
  93. package/dist/opLifecycle/remoteMessageProcessor.js.map +1 -1
  94. package/dist/opProperties.d.ts.map +1 -1
  95. package/dist/packageVersion.d.ts +1 -1
  96. package/dist/packageVersion.d.ts.map +1 -1
  97. package/dist/packageVersion.js +1 -1
  98. package/dist/packageVersion.js.map +1 -1
  99. package/dist/pendingStateManager.js +54 -47
  100. package/dist/pendingStateManager.js.map +1 -1
  101. package/dist/runCounter.js +10 -30
  102. package/dist/runCounter.js.map +1 -1
  103. package/dist/runtimeLayerCompatState.d.ts +1 -1
  104. package/dist/runtimeLayerCompatState.d.ts.map +1 -1
  105. package/dist/runtimeLayerCompatState.js +31 -11
  106. package/dist/runtimeLayerCompatState.js.map +1 -1
  107. package/dist/signalTelemetryProcessing.js +15 -17
  108. package/dist/signalTelemetryProcessing.js.map +1 -1
  109. package/dist/storageServiceWithAttachBlobs.js +2 -0
  110. package/dist/storageServiceWithAttachBlobs.js.map +1 -1
  111. package/dist/summary/documentSchema.d.ts.map +1 -1
  112. package/dist/summary/documentSchema.js +51 -13
  113. package/dist/summary/documentSchema.js.map +1 -1
  114. package/dist/summary/orderedClientElection.js +25 -17
  115. package/dist/summary/orderedClientElection.js.map +1 -1
  116. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  117. package/dist/summary/summarizerClientElection.js +18 -7
  118. package/dist/summary/summarizerClientElection.js.map +1 -1
  119. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  120. package/dist/summary/summarizerNode/summarizerNode.js +22 -13
  121. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  122. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  123. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  124. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  125. package/dist/summary/summarizerUtils.d.ts.map +1 -1
  126. package/dist/summary/summarizerUtils.js +4 -3
  127. package/dist/summary/summarizerUtils.js.map +1 -1
  128. package/dist/summary/summaryCollection.js +23 -11
  129. package/dist/summary/summaryCollection.js.map +1 -1
  130. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  131. package/dist/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  132. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  133. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  134. package/dist/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  135. package/dist/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  136. package/dist/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  137. package/dist/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  138. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  139. package/dist/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  140. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  141. package/dist/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  142. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  143. package/dist/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  144. package/dist/summary/summaryFormat.d.ts.map +1 -1
  145. package/dist/summary/summaryFormat.js +7 -7
  146. package/dist/summary/summaryFormat.js.map +1 -1
  147. package/dist/summary/summaryHelpers.js +5 -5
  148. package/dist/summary/summaryHelpers.js.map +1 -1
  149. package/dist/summary/summaryManager.js +66 -54
  150. package/dist/summary/summaryManager.js.map +1 -1
  151. package/dist/throttler.d.ts.map +1 -1
  152. package/dist/throttler.js +4 -1
  153. package/dist/throttler.js.map +1 -1
  154. package/dist/versionMarks/inboundBatch.d.ts +8 -6
  155. package/dist/versionMarks/inboundBatch.d.ts.map +1 -1
  156. package/dist/versionMarks/inboundBatch.js +11 -7
  157. package/dist/versionMarks/inboundBatch.js.map +1 -1
  158. package/dist/versionMarks/versionMarkResolver.d.ts +30 -23
  159. package/dist/versionMarks/versionMarkResolver.d.ts.map +1 -1
  160. package/dist/versionMarks/versionMarkResolver.js +112 -63
  161. package/dist/versionMarks/versionMarkResolver.js.map +1 -1
  162. package/lib/batchTracker.d.ts.map +1 -1
  163. package/lib/batchTracker.js +5 -1
  164. package/lib/batchTracker.js.map +1 -1
  165. package/lib/blobManager/blobManager.d.ts +1 -1
  166. package/lib/blobManager/blobManager.d.ts.map +1 -1
  167. package/lib/blobManager/blobManager.js +264 -231
  168. package/lib/blobManager/blobManager.js.map +1 -1
  169. package/lib/blobManager/blobManagerSnapSum.d.ts.map +1 -1
  170. package/lib/channelCollection.d.ts.map +1 -1
  171. package/lib/channelCollection.js +65 -53
  172. package/lib/channelCollection.js.map +1 -1
  173. package/lib/connectionTelemetry.js +36 -18
  174. package/lib/connectionTelemetry.js.map +1 -1
  175. package/lib/containerCompatibility.d.ts +3 -3
  176. package/lib/containerCompatibility.d.ts.map +1 -1
  177. package/lib/containerCompatibility.js +33 -42
  178. package/lib/containerCompatibility.js.map +1 -1
  179. package/lib/containerHandleContext.d.ts.map +1 -1
  180. package/lib/containerHandleContext.js +4 -0
  181. package/lib/containerHandleContext.js.map +1 -1
  182. package/lib/containerRuntime.d.ts +4 -4
  183. package/lib/containerRuntime.d.ts.map +1 -1
  184. package/lib/containerRuntime.js +341 -218
  185. package/lib/containerRuntime.js.map +1 -1
  186. package/lib/dataStore.d.ts.map +1 -1
  187. package/lib/dataStore.js +9 -1
  188. package/lib/dataStore.js.map +1 -1
  189. package/lib/dataStoreContext.d.ts.map +1 -1
  190. package/lib/dataStoreContext.js +182 -125
  191. package/lib/dataStoreContext.js.map +1 -1
  192. package/lib/dataStoreContexts.js +43 -42
  193. package/lib/dataStoreContexts.js.map +1 -1
  194. package/lib/dataStoreRegistry.js +1 -0
  195. package/lib/dataStoreRegistry.js.map +1 -1
  196. package/lib/deltaManagerProxies.js +5 -0
  197. package/lib/deltaManagerProxies.js.map +1 -1
  198. package/lib/deltaScheduler.js +104 -99
  199. package/lib/deltaScheduler.js.map +1 -1
  200. package/lib/error.js +2 -1
  201. package/lib/error.js.map +1 -1
  202. package/lib/gc/garbageCollection.js +85 -55
  203. package/lib/gc/garbageCollection.js.map +1 -1
  204. package/lib/gc/gcSummaryStateTracker.js +8 -3
  205. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  206. package/lib/gc/gcTelemetry.js +12 -5
  207. package/lib/gc/gcTelemetry.js.map +1 -1
  208. package/lib/gc/gcUnreferencedStateTracker.js +18 -1
  209. package/lib/gc/gcUnreferencedStateTracker.js.map +1 -1
  210. package/lib/inboundBatchAggregator.js +122 -117
  211. package/lib/inboundBatchAggregator.js.map +1 -1
  212. package/lib/legacy.d.ts +1 -1
  213. package/lib/legacyAlpha.d.ts +1 -1
  214. package/lib/metadata.d.ts.map +1 -1
  215. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  216. package/lib/opLifecycle/batchManager.js +8 -2
  217. package/lib/opLifecycle/batchManager.js.map +1 -1
  218. package/lib/opLifecycle/duplicateBatchDetector.js +18 -18
  219. package/lib/opLifecycle/duplicateBatchDetector.js.map +1 -1
  220. package/lib/opLifecycle/index.d.ts +2 -2
  221. package/lib/opLifecycle/index.d.ts.map +1 -1
  222. package/lib/opLifecycle/index.js +2 -2
  223. package/lib/opLifecycle/index.js.map +1 -1
  224. package/lib/opLifecycle/opCompressor.js +3 -2
  225. package/lib/opLifecycle/opCompressor.js.map +1 -1
  226. package/lib/opLifecycle/opDecompressor.js +10 -6
  227. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  228. package/lib/opLifecycle/opGroupingManager.js +3 -1
  229. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  230. package/lib/opLifecycle/opSerialization.d.ts +11 -1
  231. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  232. package/lib/opLifecycle/opSerialization.js +16 -0
  233. package/lib/opLifecycle/opSerialization.js.map +1 -1
  234. package/lib/opLifecycle/opSplitter.d.ts +17 -1
  235. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  236. package/lib/opLifecycle/opSplitter.js +44 -7
  237. package/lib/opLifecycle/opSplitter.js.map +1 -1
  238. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  239. package/lib/opLifecycle/outbox.js +14 -10
  240. package/lib/opLifecycle/outbox.js.map +1 -1
  241. package/lib/opLifecycle/remoteMessageProcessor.js +4 -1
  242. package/lib/opLifecycle/remoteMessageProcessor.js.map +1 -1
  243. package/lib/opProperties.d.ts.map +1 -1
  244. package/lib/packageVersion.d.ts +1 -1
  245. package/lib/packageVersion.d.ts.map +1 -1
  246. package/lib/packageVersion.js +1 -1
  247. package/lib/packageVersion.js.map +1 -1
  248. package/lib/pendingStateManager.js +52 -45
  249. package/lib/pendingStateManager.js.map +1 -1
  250. package/lib/public.d.ts +1 -1
  251. package/lib/runCounter.js +10 -30
  252. package/lib/runCounter.js.map +1 -1
  253. package/lib/runtimeLayerCompatState.d.ts +1 -1
  254. package/lib/runtimeLayerCompatState.d.ts.map +1 -1
  255. package/lib/runtimeLayerCompatState.js +28 -8
  256. package/lib/runtimeLayerCompatState.js.map +1 -1
  257. package/lib/signalTelemetryProcessing.js +15 -17
  258. package/lib/signalTelemetryProcessing.js.map +1 -1
  259. package/lib/storageServiceWithAttachBlobs.js +2 -0
  260. package/lib/storageServiceWithAttachBlobs.js.map +1 -1
  261. package/lib/summary/documentSchema.d.ts.map +1 -1
  262. package/lib/summary/documentSchema.js +51 -13
  263. package/lib/summary/documentSchema.js.map +1 -1
  264. package/lib/summary/orderedClientElection.js +25 -17
  265. package/lib/summary/orderedClientElection.js.map +1 -1
  266. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  267. package/lib/summary/summarizerClientElection.js +18 -7
  268. package/lib/summary/summarizerClientElection.js.map +1 -1
  269. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  270. package/lib/summary/summarizerNode/summarizerNode.js +22 -13
  271. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  272. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  273. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +20 -6
  274. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  275. package/lib/summary/summarizerUtils.d.ts.map +1 -1
  276. package/lib/summary/summarizerUtils.js +1 -0
  277. package/lib/summary/summarizerUtils.js.map +1 -1
  278. package/lib/summary/summaryCollection.js +23 -11
  279. package/lib/summary/summaryCollection.js.map +1 -1
  280. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js +4 -2
  281. package/lib/summary/summaryDelayLoadedModule/runWhileConnectedCoordinator.js.map +1 -1
  282. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.d.ts.map +1 -1
  283. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js +65 -46
  284. package/lib/summary/summaryDelayLoadedModule/runningSummarizer.js.map +1 -1
  285. package/lib/summary/summaryDelayLoadedModule/summarizer.d.ts.map +1 -1
  286. package/lib/summary/summaryDelayLoadedModule/summarizer.js +15 -6
  287. package/lib/summary/summaryDelayLoadedModule/summarizer.js.map +1 -1
  288. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js +30 -25
  289. package/lib/summary/summaryDelayLoadedModule/summarizerHeuristics.js.map +1 -1
  290. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js +9 -0
  291. package/lib/summary/summaryDelayLoadedModule/summaryGenerator.js.map +1 -1
  292. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js +3 -5
  293. package/lib/summary/summaryDelayLoadedModule/summaryResultBuilder.js.map +1 -1
  294. package/lib/summary/summaryFormat.d.ts.map +1 -1
  295. package/lib/summary/summaryManager.js +66 -54
  296. package/lib/summary/summaryManager.js.map +1 -1
  297. package/lib/throttler.d.ts.map +1 -1
  298. package/lib/throttler.js +4 -1
  299. package/lib/throttler.js.map +1 -1
  300. package/lib/versionMarks/inboundBatch.d.ts +8 -6
  301. package/lib/versionMarks/inboundBatch.d.ts.map +1 -1
  302. package/lib/versionMarks/inboundBatch.js +10 -5
  303. package/lib/versionMarks/inboundBatch.js.map +1 -1
  304. package/lib/versionMarks/versionMarkResolver.d.ts +30 -23
  305. package/lib/versionMarks/versionMarkResolver.d.ts.map +1 -1
  306. package/lib/versionMarks/versionMarkResolver.js +112 -63
  307. package/lib/versionMarks/versionMarkResolver.js.map +1 -1
  308. package/package.json +60 -102
  309. package/src/containerCompatibility.ts +33 -42
  310. package/src/containerRuntime.ts +15 -12
  311. package/src/opLifecycle/index.ts +7 -1
  312. package/src/opLifecycle/opCompressor.ts +2 -2
  313. package/src/opLifecycle/opSerialization.ts +22 -1
  314. package/src/opLifecycle/opSplitter.ts +63 -6
  315. package/src/packageVersion.ts +1 -1
  316. package/src/runtimeLayerCompatState.ts +28 -21
  317. package/src/summary/documentSchema.ts +31 -6
  318. package/src/versionMarks/DEV.md +595 -157
  319. package/src/versionMarks/inboundBatch.ts +18 -8
  320. package/src/versionMarks/versionMarkResolver.ts +144 -75
  321. package/tsconfig.json +1 -1
  322. package/internal.d.ts +0 -11
  323. package/legacy/alpha.d.ts +0 -11
  324. package/legacy.d.ts +0 -11
  325. /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
  326. /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
@@ -3,7 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import type { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
6
+ import {
7
+ MessageType,
8
+ type ISequencedDocumentMessage,
9
+ } from "@fluidframework/driver-definitions/internal";
7
10
  import {
8
11
  encodeHandleForSerialization,
9
12
  isFluidHandle,
@@ -29,6 +32,24 @@ export function ensureContentsDeserialized(mutableMessage: ISequencedDocumentMes
29
32
  }
30
33
  }
31
34
 
35
+ /**
36
+ * If `message` is a modern runtime-envelope op (type "op" with a client id), returns a shallow copy
37
+ * with its contents deserialized ({@link ensureContentsDeserialized}); otherwise `undefined`.
38
+ *
39
+ * @remarks Only runtime ops may be deserialized (system ops carry non-JSON payloads), and copying keeps
40
+ * the caller's op untouched for the unpack pipeline. Shared so callers don't re-derive the invariant.
41
+ */
42
+ export function tryGetDeserializedRuntimeOpCopy(
43
+ message: ISequencedDocumentMessage,
44
+ ): (ISequencedDocumentMessage & { clientId: string }) | undefined {
45
+ if (message.type !== MessageType.Operation || typeof message.clientId !== "string") {
46
+ return undefined;
47
+ }
48
+ const messageCopy = { ...message };
49
+ ensureContentsDeserialized(messageCopy);
50
+ return messageCopy as ISequencedDocumentMessage & { clientId: string };
51
+ }
52
+
32
53
  /**
33
54
  * Before submitting an op to the Outbox, its contents must be serialized using this function.
34
55
  * @remarks The deserialization on process happens via the function {@link ensureContentsDeserialized}.
@@ -30,6 +30,20 @@ export function isChunkedMessage(message: ISequencedDocumentMessage): boolean {
30
30
  return isChunkedContents(message.contents);
31
31
  }
32
32
 
33
+ /**
34
+ * Configures inbound chunk processing.
35
+ *
36
+ * @internal
37
+ */
38
+ export interface OpSplitterOptions {
39
+ /**
40
+ * Allows the first observed chunk stream for each client to begin after chunk 1. The unreconstructable
41
+ * remainder of that stream is discarded, after which chunk ordering is strict. Historical readers use
42
+ * this because their requested range can begin within a stream; live processing leaves it disabled.
43
+ */
44
+ readonly allowInitialPartialChunkStream?: boolean;
45
+ }
46
+
33
47
  interface IChunkedContents {
34
48
  readonly type: typeof ContainerMessageType.ChunkedOp;
35
49
  readonly contents: IChunkedOp;
@@ -45,6 +59,8 @@ function isChunkedContents(contents: unknown): contents is IChunkedContents {
45
59
  export class OpSplitter {
46
60
  // Local copy of incomplete received chunks.
47
61
  private readonly chunkMap: Map<string, string[]>;
62
+ // No entry = unseen; 1 = aligned; >1 = the next initial partial chunk to discard.
63
+ private readonly nextInitialChunkIdByClient = new Map<string, number>();
48
64
  private readonly logger: TelemetryLoggerExt;
49
65
 
50
66
  constructor(
@@ -55,8 +71,14 @@ export class OpSplitter {
55
71
  public readonly chunkSizeInBytes: number,
56
72
  private readonly maxBatchSizeInBytes: number,
57
73
  logger: ITelemetryBaseLogger,
74
+ private readonly options: OpSplitterOptions = {},
58
75
  ) {
59
76
  this.chunkMap = new Map<string, string[]>(chunks);
77
+ if (this.options.allowInitialPartialChunkStream === true) {
78
+ for (const clientId of this.chunkMap.keys()) {
79
+ this.nextInitialChunkIdByClient.set(clientId, 1);
80
+ }
81
+ }
60
82
  this.logger = createChildLogger({ logger, namespace: "OpSplitter" });
61
83
  }
62
84
 
@@ -76,6 +98,19 @@ export class OpSplitter {
76
98
  }
77
99
  }
78
100
 
101
+ private throwChunkIdMismatch(
102
+ originalMessage: ISequencedDocumentMessage,
103
+ chunkedContent: IChunkedOp,
104
+ expectedChunkId: number,
105
+ ): never {
106
+ throw new DataCorruptionError("Chunk Id mismatch", {
107
+ ...extractSafePropertiesFromMessage(originalMessage),
108
+ chunkMapLength: expectedChunkId - 1,
109
+ chunkId: chunkedContent.chunkId,
110
+ totalChunks: chunkedContent.totalChunks,
111
+ });
112
+ }
113
+
79
114
  private addChunk(
80
115
  clientId: string,
81
116
  chunkedContent: IChunkedOp,
@@ -91,12 +126,7 @@ export class OpSplitter {
91
126
  // We are expecting the chunks to be processed sequentially, in the same order as they are sent.
92
127
  // Therefore, the chunkId of the incoming op needs to match the length of the array (1-based indexing)
93
128
  // holding the existing chunks for that particular clientId.
94
- throw new DataCorruptionError("Chunk Id mismatch", {
95
- ...extractSafePropertiesFromMessage(originalMessage),
96
- chunkMapLength: map.length,
97
- chunkId: chunkedContent.chunkId,
98
- totalChunks: chunkedContent.totalChunks,
99
- });
129
+ this.throwChunkIdMismatch(originalMessage, chunkedContent, map.length + 1);
100
130
  }
101
131
 
102
132
  map.push(chunkedContent.contents);
@@ -214,6 +244,33 @@ export class OpSplitter {
214
244
 
215
245
  const clientId = message.clientId as string;
216
246
  const chunkedContent = contents.contents;
247
+ if (this.options.allowInitialPartialChunkStream === true) {
248
+ const nextInitialChunkId = this.nextInitialChunkIdByClient.get(clientId);
249
+ if (nextInitialChunkId !== 1) {
250
+ if (
251
+ nextInitialChunkId !== undefined &&
252
+ chunkedContent.chunkId !== nextInitialChunkId
253
+ ) {
254
+ this.throwChunkIdMismatch(message, chunkedContent, nextInitialChunkId);
255
+ }
256
+
257
+ if (
258
+ nextInitialChunkId === undefined &&
259
+ (chunkedContent.chunkId <= 1 || chunkedContent.chunkId > chunkedContent.totalChunks)
260
+ ) {
261
+ this.nextInitialChunkIdByClient.set(clientId, 1);
262
+ } else {
263
+ this.nextInitialChunkIdByClient.set(
264
+ clientId,
265
+ chunkedContent.chunkId < chunkedContent.totalChunks
266
+ ? chunkedContent.chunkId + 1
267
+ : 1,
268
+ );
269
+ return { isFinalChunk: false };
270
+ }
271
+ }
272
+ }
273
+
217
274
  this.addChunk(clientId, chunkedContent, message);
218
275
 
219
276
  if (chunkedContent.chunkId < chunkedContent.totalChunks) {
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.118.1";
9
+ export const pkgVersion = "3.0.1";
@@ -61,13 +61,14 @@ export const runtimeCompatDetailsForLoader: ILayerCompatDetails = {
61
61
  export const loaderSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {
62
62
  /**
63
63
  * Minimum generation that Loader must be at to be compatible with this Runtime. This is calculated
64
- * based on the LayerCompatibilityPolicyWindowMonths.RuntimeLoader value which defines how many months old can
65
- * the Loader layer be compared to the Runtime layer for them to still be considered compatible.
64
+ * based on the LayerCompatibilityPolicyWindowMonths.NewRuntimeOldLoader value which defines how many months
65
+ * old can the Loader layer be compared to the Runtime layer for them to still be considered compatible.
66
66
  * The minimum valid generation value is 0.
67
67
  */
68
68
  minSupportedGeneration: Math.max(
69
69
  0,
70
- runtimeCoreCompatDetails.generation - LayerCompatibilityPolicyWindowMonths.RuntimeLoader,
70
+ runtimeCoreCompatDetails.generation -
71
+ LayerCompatibilityPolicyWindowMonths.NewRuntimeOldLoader,
71
72
  ),
72
73
  /**
73
74
  * The features that the Loader must support to be compatible with Runtime.
@@ -94,14 +95,14 @@ export const runtimeCompatDetailsForDataStore: ILayerCompatDetails = {
94
95
  export const dataStoreSupportRequirementsForRuntime: ILayerCompatSupportRequirements = {
95
96
  /**
96
97
  * Minimum generation that DataStore must be at to be compatible with this Runtime. This is calculated
97
- * based on the LayerCompatibilityPolicyWindowMonths.RuntimeDataStore value which defines how many months old can
98
- * the DataStore layer be compared to the Runtime layer for them to still be considered compatible.
98
+ * based on the LayerCompatibilityPolicyWindowMonths.NewRuntimeOldDataStore value which defines how many months
99
+ * old can the DataStore layer be compared to the Runtime layer for them to still be considered compatible.
99
100
  * The minimum valid generation value is 0.
100
101
  */
101
102
  minSupportedGeneration: Math.max(
102
103
  0,
103
104
  runtimeCoreCompatDetails.generation -
104
- LayerCompatibilityPolicyWindowMonths.RuntimeDataStore,
105
+ LayerCompatibilityPolicyWindowMonths.NewRuntimeOldDataStore,
105
106
  ),
106
107
  /**
107
108
  * The features that the DataStore must support to be compatible with Runtime.
@@ -127,14 +128,17 @@ export function validateLoaderCompatibility(
127
128
  );
128
129
 
129
130
  validateLayerCompatibility(
130
- "runtime",
131
- "loader",
132
- runtimeCompatDetailsForLoader,
133
- loaderSupportRequirementsForRuntime,
134
- maybeLoaderCompatDetailsForRuntime,
135
- disposeFn,
136
- mc,
137
- disableStrictLoaderLayerCompatibilityCheck !== true /* strictCompatibilityCheck */,
131
+ /* validatingLayer */ {
132
+ layer: "runtime",
133
+ packageInfo: runtimeCoreCompatDetails,
134
+ compatSupportRequirements: loaderSupportRequirementsForRuntime,
135
+ },
136
+ /* targetLayer */ {
137
+ layer: "loader",
138
+ compatDetails: maybeLoaderCompatDetailsForRuntime,
139
+ strictCompatibilityCheck: disableStrictLoaderLayerCompatibilityCheck !== true,
140
+ },
141
+ { disposeFn, mc },
138
142
  );
139
143
  }
140
144
 
@@ -148,12 +152,15 @@ export function validateDatastoreCompatibility(
148
152
  mc: MonitoringContext,
149
153
  ): void {
150
154
  validateLayerCompatibility(
151
- "runtime",
152
- "dataStore",
153
- runtimeCompatDetailsForDataStore,
154
- dataStoreSupportRequirementsForRuntime,
155
- maybeDataStoreCompatDetailsForRuntime,
156
- disposeFn,
157
- mc,
155
+ /* validatingLayer */ {
156
+ layer: "runtime",
157
+ packageInfo: runtimeCoreCompatDetails,
158
+ compatSupportRequirements: dataStoreSupportRequirementsForRuntime,
159
+ },
160
+ /* targetLayer */ {
161
+ layer: "dataStore",
162
+ compatDetails: maybeDataStoreCompatDetailsForRuntime,
163
+ },
164
+ { disposeFn, mc },
158
165
  );
159
166
  }
@@ -436,9 +436,11 @@ function and(
436
436
  }
437
437
 
438
438
  // We keep the persisted minVersionForCollab if present, even if the provided minVersionForCollab
439
- // is higher.
439
+ // is higher, after migrating historical 2.x prerelease values to their stable versions.
440
440
  const minVersionForCollab =
441
- persistedSchema.info?.minVersionForCollab ?? providedSchema.info.minVersionForCollab;
441
+ persistedSchema.info === undefined
442
+ ? providedSchema.info.minVersionForCollab
443
+ : normalizePersistedMinVersionForCollab(persistedSchema.info.minVersionForCollab);
442
444
 
443
445
  return {
444
446
  version: currentDocumentVersionSchema,
@@ -463,12 +465,16 @@ function or(
463
465
  );
464
466
  }
465
467
 
466
- // We take the greater of the persisted/provided minVersionForCollab
467
- const minVersionForCollab =
468
+ // We take the greater of the normalized persisted/provided minVersionForCollab.
469
+ const persistedMinVersionForCollab =
468
470
  persistedSchema.info === undefined
471
+ ? undefined
472
+ : normalizePersistedMinVersionForCollab(persistedSchema.info.minVersionForCollab);
473
+ const minVersionForCollab =
474
+ persistedMinVersionForCollab === undefined
469
475
  ? providedSchema.info.minVersionForCollab
470
- : gt(persistedSchema.info.minVersionForCollab, providedSchema.info.minVersionForCollab)
471
- ? persistedSchema.info.minVersionForCollab
476
+ : gt(persistedMinVersionForCollab, providedSchema.info.minVersionForCollab)
477
+ ? persistedMinVersionForCollab
472
478
  : providedSchema.info.minVersionForCollab;
473
479
 
474
480
  return {
@@ -479,6 +485,25 @@ function or(
479
485
  };
480
486
  }
481
487
 
488
+ /**
489
+ * Migrates 2.x prerelease values accepted by older clients to the corresponding stable version.
490
+ *
491
+ * @remarks
492
+ * This is monotonic under SemVer and can cross a compatibility checkpoint when the prerelease
493
+ * shares that checkpoint's major, minor, and patch. Client 3.0 no longer supports active
494
+ * prerelease collaborators, so the persisted requirement advances before format selection.
495
+ */
496
+ function normalizePersistedMinVersionForCollab(
497
+ minVersionForCollab: SemanticVersion,
498
+ ): SemanticVersion {
499
+ const parsed = parse(minVersionForCollab);
500
+ if (parsed?.major === 2 && parsed.prerelease.length > 0) {
501
+ // `parse` validates each numeric component before this template is constructed.
502
+ return `${parsed.major}.${parsed.minor}.${parsed.patch}` as SemanticVersion;
503
+ }
504
+ return minVersionForCollab;
505
+ }
506
+
482
507
  /**
483
508
  * Determines if two schemas are the "same".
484
509
  * Schemas are considered **not** the same if a schema change op is required to make