@fluidframework/container-runtime 2.0.0-dev-rc.5.0.0.271717 → 2.0.0-dev-rc.5.0.0.272889

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 (257) hide show
  1. package/api-extractor/api-extractor-lint-bundle.json +5 -0
  2. package/api-extractor/api-extractor-lint-legacy.cjs.json +5 -0
  3. package/api-extractor/api-extractor-lint-legacy.esm.json +5 -0
  4. package/api-extractor/api-extractor-lint-public.cjs.json +5 -0
  5. package/api-extractor/api-extractor-lint-public.esm.json +5 -0
  6. package/api-extractor.json +1 -1
  7. package/api-report/container-runtime.alpha.api.md +1 -1
  8. package/container-runtime.test-files.tar +0 -0
  9. package/dist/batchTracker.d.ts.map +1 -1
  10. package/dist/batchTracker.js.map +1 -1
  11. package/dist/blobManager.d.ts.map +1 -1
  12. package/dist/blobManager.js.map +1 -1
  13. package/dist/channelCollection.d.ts +12 -2
  14. package/dist/channelCollection.d.ts.map +1 -1
  15. package/dist/channelCollection.js +86 -90
  16. package/dist/channelCollection.js.map +1 -1
  17. package/dist/connectionTelemetry.d.ts.map +1 -1
  18. package/dist/connectionTelemetry.js.map +1 -1
  19. package/dist/containerRuntime.d.ts +2 -1
  20. package/dist/containerRuntime.d.ts.map +1 -1
  21. package/dist/containerRuntime.js +29 -9
  22. package/dist/containerRuntime.js.map +1 -1
  23. package/dist/dataStoreContext.d.ts +2 -1
  24. package/dist/dataStoreContext.d.ts.map +1 -1
  25. package/dist/dataStoreContext.js +5 -3
  26. package/dist/dataStoreContext.js.map +1 -1
  27. package/dist/dataStoreContexts.d.ts.map +1 -1
  28. package/dist/dataStoreContexts.js.map +1 -1
  29. package/dist/deltaManagerProxies.d.ts.map +1 -1
  30. package/dist/deltaManagerProxies.js.map +1 -1
  31. package/dist/deltaScheduler.d.ts.map +1 -1
  32. package/dist/deltaScheduler.js +1 -3
  33. package/dist/deltaScheduler.js.map +1 -1
  34. package/dist/gc/garbageCollection.d.ts +4 -2
  35. package/dist/gc/garbageCollection.d.ts.map +1 -1
  36. package/dist/gc/garbageCollection.js +12 -8
  37. package/dist/gc/garbageCollection.js.map +1 -1
  38. package/dist/gc/gcConfigs.js +1 -1
  39. package/dist/gc/gcConfigs.js.map +1 -1
  40. package/dist/gc/gcDefinitions.d.ts +7 -4
  41. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  42. package/dist/gc/gcDefinitions.js.map +1 -1
  43. package/dist/gc/gcHelpers.d.ts.map +1 -1
  44. package/dist/gc/gcHelpers.js.map +1 -1
  45. package/dist/gc/gcSummaryStateTracker.d.ts.map +1 -1
  46. package/dist/gc/gcSummaryStateTracker.js.map +1 -1
  47. package/dist/gc/gcTelemetry.d.ts +1 -1
  48. package/dist/gc/gcTelemetry.d.ts.map +1 -1
  49. package/dist/gc/gcTelemetry.js +1 -7
  50. package/dist/gc/gcTelemetry.js.map +1 -1
  51. package/dist/index.d.ts +1 -1
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js.map +1 -1
  54. package/dist/messageTypes.d.ts +5 -21
  55. package/dist/messageTypes.d.ts.map +1 -1
  56. package/dist/messageTypes.js.map +1 -1
  57. package/dist/opLifecycle/index.d.ts +1 -1
  58. package/dist/opLifecycle/index.d.ts.map +1 -1
  59. package/dist/opLifecycle/index.js.map +1 -1
  60. package/dist/opLifecycle/opDecompressor.d.ts.map +1 -1
  61. package/dist/opLifecycle/opDecompressor.js +1 -2
  62. package/dist/opLifecycle/opDecompressor.js.map +1 -1
  63. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  64. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  65. package/dist/opLifecycle/opSplitter.d.ts.map +1 -1
  66. package/dist/opLifecycle/opSplitter.js +1 -1
  67. package/dist/opLifecycle/opSplitter.js.map +1 -1
  68. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  69. package/dist/opLifecycle/outbox.js.map +1 -1
  70. package/dist/packageVersion.d.ts +1 -1
  71. package/dist/packageVersion.js +1 -1
  72. package/dist/packageVersion.js.map +1 -1
  73. package/dist/pendingStateManager.d.ts.map +1 -1
  74. package/dist/pendingStateManager.js +1 -1
  75. package/dist/pendingStateManager.js.map +1 -1
  76. package/dist/summary/documentSchema.d.ts.map +1 -1
  77. package/dist/summary/documentSchema.js +1 -2
  78. package/dist/summary/documentSchema.js.map +1 -1
  79. package/dist/summary/index.d.ts +1 -1
  80. package/dist/summary/index.d.ts.map +1 -1
  81. package/dist/summary/index.js.map +1 -1
  82. package/dist/summary/orderedClientElection.d.ts.map +1 -1
  83. package/dist/summary/orderedClientElection.js.map +1 -1
  84. package/dist/summary/runningSummarizer.d.ts.map +1 -1
  85. package/dist/summary/runningSummarizer.js +1 -2
  86. package/dist/summary/runningSummarizer.js.map +1 -1
  87. package/dist/summary/summarizerClientElection.d.ts.map +1 -1
  88. package/dist/summary/summarizerClientElection.js.map +1 -1
  89. package/dist/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  90. package/dist/summary/summarizerNode/summarizerNode.js.map +1 -1
  91. package/dist/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  92. package/dist/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  93. package/dist/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  94. package/dist/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
  95. package/dist/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  96. package/dist/summary/summarizerTypes.d.ts.map +1 -1
  97. package/dist/summary/summarizerTypes.js.map +1 -1
  98. package/dist/summary/summaryCollection.d.ts.map +1 -1
  99. package/dist/summary/summaryCollection.js.map +1 -1
  100. package/dist/summary/summaryFormat.d.ts.map +1 -1
  101. package/dist/summary/summaryFormat.js.map +1 -1
  102. package/dist/summary/summaryGenerator.d.ts.map +1 -1
  103. package/dist/summary/summaryGenerator.js +1 -2
  104. package/dist/summary/summaryGenerator.js.map +1 -1
  105. package/dist/summary/summaryManager.d.ts.map +1 -1
  106. package/dist/summary/summaryManager.js +1 -2
  107. package/dist/summary/summaryManager.js.map +1 -1
  108. package/dist/throttler.d.ts.map +1 -1
  109. package/dist/throttler.js +3 -1
  110. package/dist/throttler.js.map +1 -1
  111. package/lib/batchTracker.d.ts.map +1 -1
  112. package/lib/batchTracker.js +1 -1
  113. package/lib/batchTracker.js.map +1 -1
  114. package/lib/blobManager.d.ts.map +1 -1
  115. package/lib/blobManager.js +1 -1
  116. package/lib/blobManager.js.map +1 -1
  117. package/lib/channelCollection.d.ts +12 -2
  118. package/lib/channelCollection.d.ts.map +1 -1
  119. package/lib/channelCollection.js +86 -90
  120. package/lib/channelCollection.js.map +1 -1
  121. package/lib/connectionTelemetry.d.ts.map +1 -1
  122. package/lib/connectionTelemetry.js.map +1 -1
  123. package/lib/containerRuntime.d.ts +2 -1
  124. package/lib/containerRuntime.d.ts.map +1 -1
  125. package/lib/containerRuntime.js +32 -12
  126. package/lib/containerRuntime.js.map +1 -1
  127. package/lib/dataStoreContext.d.ts +2 -1
  128. package/lib/dataStoreContext.d.ts.map +1 -1
  129. package/lib/dataStoreContext.js +5 -3
  130. package/lib/dataStoreContext.js.map +1 -1
  131. package/lib/dataStoreContexts.d.ts.map +1 -1
  132. package/lib/dataStoreContexts.js +1 -1
  133. package/lib/dataStoreContexts.js.map +1 -1
  134. package/lib/deltaManagerProxies.d.ts.map +1 -1
  135. package/lib/deltaManagerProxies.js.map +1 -1
  136. package/lib/deltaScheduler.d.ts.map +1 -1
  137. package/lib/deltaScheduler.js +1 -3
  138. package/lib/deltaScheduler.js.map +1 -1
  139. package/lib/gc/garbageCollection.d.ts +4 -2
  140. package/lib/gc/garbageCollection.d.ts.map +1 -1
  141. package/lib/gc/garbageCollection.js +13 -9
  142. package/lib/gc/garbageCollection.js.map +1 -1
  143. package/lib/gc/gcConfigs.js +1 -1
  144. package/lib/gc/gcConfigs.js.map +1 -1
  145. package/lib/gc/gcDefinitions.d.ts +7 -4
  146. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  147. package/lib/gc/gcDefinitions.js.map +1 -1
  148. package/lib/gc/gcHelpers.d.ts.map +1 -1
  149. package/lib/gc/gcHelpers.js.map +1 -1
  150. package/lib/gc/gcSummaryStateTracker.d.ts.map +1 -1
  151. package/lib/gc/gcSummaryStateTracker.js.map +1 -1
  152. package/lib/gc/gcTelemetry.d.ts +1 -1
  153. package/lib/gc/gcTelemetry.d.ts.map +1 -1
  154. package/lib/gc/gcTelemetry.js +1 -7
  155. package/lib/gc/gcTelemetry.js.map +1 -1
  156. package/lib/index.d.ts +1 -1
  157. package/lib/index.d.ts.map +1 -1
  158. package/lib/index.js.map +1 -1
  159. package/lib/messageTypes.d.ts +5 -21
  160. package/lib/messageTypes.d.ts.map +1 -1
  161. package/lib/messageTypes.js.map +1 -1
  162. package/lib/opLifecycle/index.d.ts +1 -1
  163. package/lib/opLifecycle/index.d.ts.map +1 -1
  164. package/lib/opLifecycle/index.js +1 -1
  165. package/lib/opLifecycle/index.js.map +1 -1
  166. package/lib/opLifecycle/opDecompressor.d.ts.map +1 -1
  167. package/lib/opLifecycle/opDecompressor.js +1 -2
  168. package/lib/opLifecycle/opDecompressor.js.map +1 -1
  169. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  170. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  171. package/lib/opLifecycle/opSplitter.d.ts.map +1 -1
  172. package/lib/opLifecycle/opSplitter.js +1 -1
  173. package/lib/opLifecycle/opSplitter.js.map +1 -1
  174. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  175. package/lib/opLifecycle/outbox.js.map +1 -1
  176. package/lib/packageVersion.d.ts +1 -1
  177. package/lib/packageVersion.js +1 -1
  178. package/lib/packageVersion.js.map +1 -1
  179. package/lib/pendingStateManager.d.ts.map +1 -1
  180. package/lib/pendingStateManager.js +1 -1
  181. package/lib/pendingStateManager.js.map +1 -1
  182. package/lib/summary/documentSchema.d.ts.map +1 -1
  183. package/lib/summary/documentSchema.js +1 -2
  184. package/lib/summary/documentSchema.js.map +1 -1
  185. package/lib/summary/index.d.ts +1 -1
  186. package/lib/summary/index.d.ts.map +1 -1
  187. package/lib/summary/index.js +1 -1
  188. package/lib/summary/index.js.map +1 -1
  189. package/lib/summary/orderedClientElection.d.ts.map +1 -1
  190. package/lib/summary/orderedClientElection.js.map +1 -1
  191. package/lib/summary/runningSummarizer.d.ts.map +1 -1
  192. package/lib/summary/runningSummarizer.js +1 -2
  193. package/lib/summary/runningSummarizer.js.map +1 -1
  194. package/lib/summary/summarizerClientElection.d.ts.map +1 -1
  195. package/lib/summary/summarizerClientElection.js.map +1 -1
  196. package/lib/summary/summarizerNode/summarizerNode.d.ts.map +1 -1
  197. package/lib/summary/summarizerNode/summarizerNode.js.map +1 -1
  198. package/lib/summary/summarizerNode/summarizerNodeUtils.d.ts.map +1 -1
  199. package/lib/summary/summarizerNode/summarizerNodeUtils.js.map +1 -1
  200. package/lib/summary/summarizerNode/summarizerNodeWithGc.d.ts.map +1 -1
  201. package/lib/summary/summarizerNode/summarizerNodeWithGc.js +4 -1
  202. package/lib/summary/summarizerNode/summarizerNodeWithGc.js.map +1 -1
  203. package/lib/summary/summarizerTypes.d.ts.map +1 -1
  204. package/lib/summary/summarizerTypes.js.map +1 -1
  205. package/lib/summary/summaryCollection.d.ts.map +1 -1
  206. package/lib/summary/summaryCollection.js.map +1 -1
  207. package/lib/summary/summaryFormat.d.ts.map +1 -1
  208. package/lib/summary/summaryFormat.js.map +1 -1
  209. package/lib/summary/summaryGenerator.d.ts.map +1 -1
  210. package/lib/summary/summaryGenerator.js +1 -2
  211. package/lib/summary/summaryGenerator.js.map +1 -1
  212. package/lib/summary/summaryManager.d.ts.map +1 -1
  213. package/lib/summary/summaryManager.js +1 -2
  214. package/lib/summary/summaryManager.js.map +1 -1
  215. package/lib/throttler.d.ts.map +1 -1
  216. package/lib/throttler.js +3 -1
  217. package/lib/throttler.js.map +1 -1
  218. package/package.json +33 -20
  219. package/src/batchTracker.ts +4 -1
  220. package/src/blobManager.ts +14 -16
  221. package/src/channelCollection.ts +139 -132
  222. package/src/connectionTelemetry.ts +3 -8
  223. package/src/containerRuntime.ts +72 -44
  224. package/src/dataStoreContext.ts +34 -11
  225. package/src/dataStoreContexts.ts +7 -2
  226. package/src/deltaManagerProxies.ts +12 -3
  227. package/src/deltaScheduler.ts +1 -3
  228. package/src/gc/garbageCollection.ts +47 -31
  229. package/src/gc/gcConfigs.ts +7 -3
  230. package/src/gc/gcDefinitions.ts +16 -4
  231. package/src/gc/gcHelpers.ts +6 -2
  232. package/src/gc/gcSummaryStateTracker.ts +4 -1
  233. package/src/gc/gcTelemetry.ts +2 -9
  234. package/src/index.ts +0 -1
  235. package/src/messageTypes.ts +7 -23
  236. package/src/opLifecycle/index.ts +5 -1
  237. package/src/opLifecycle/opDecompressor.ts +2 -6
  238. package/src/opLifecycle/opGroupingManager.ts +1 -4
  239. package/src/opLifecycle/opSplitter.ts +9 -3
  240. package/src/opLifecycle/outbox.ts +1 -4
  241. package/src/packageVersion.ts +1 -1
  242. package/src/pendingStateManager.ts +4 -2
  243. package/src/summary/documentSchema.ts +4 -7
  244. package/src/summary/index.ts +4 -1
  245. package/src/summary/orderedClientElection.ts +17 -10
  246. package/src/summary/runningSummarizer.ts +20 -9
  247. package/src/summary/summarizerClientElection.ts +2 -1
  248. package/src/summary/summarizerNode/summarizerNode.ts +6 -4
  249. package/src/summary/summarizerNode/summarizerNodeUtils.ts +7 -2
  250. package/src/summary/summarizerNode/summarizerNodeWithGc.ts +10 -6
  251. package/src/summary/summarizerTypes.ts +9 -2
  252. package/src/summary/summaryCollection.ts +4 -1
  253. package/src/summary/summaryFormat.ts +8 -3
  254. package/src/summary/summaryGenerator.ts +4 -9
  255. package/src/summary/summaryManager.ts +6 -9
  256. package/src/throttler.ts +3 -1
  257. package/tsdoc.json +4 -0
@@ -94,7 +94,10 @@ function createAttributes(
94
94
  isRootDataStore,
95
95
  };
96
96
  }
97
- export function createAttributesBlob(pkg: readonly string[], isRootDataStore: boolean): ITreeEntry {
97
+ export function createAttributesBlob(
98
+ pkg: readonly string[],
99
+ isRootDataStore: boolean,
100
+ ): ITreeEntry {
98
101
  const attributes = createAttributes(pkg, isRootDataStore);
99
102
  return new BlobTreeEntry(dataStoreAttributesBlobName, JSON.stringify(attributes));
100
103
  }
@@ -157,7 +160,8 @@ export interface ILocalFluidDataStoreContextProps extends IFluidDataStoreContext
157
160
  * Properties necessary for creating a local FluidDataStoreContext
158
161
  * @internal
159
162
  */
160
- export interface ILocalDetachedFluidDataStoreContextProps extends ILocalFluidDataStoreContextProps {
163
+ export interface ILocalDetachedFluidDataStoreContextProps
164
+ extends ILocalFluidDataStoreContextProps {
161
165
  readonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;
162
166
  }
163
167
 
@@ -431,7 +435,9 @@ export abstract class FluidDataStoreContext
431
435
  this._tombstoned = tombstone;
432
436
  }
433
437
 
434
- public abstract setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void;
438
+ public abstract setAttachState(
439
+ attachState: AttachState.Attaching | AttachState.Attached,
440
+ ): void;
435
441
 
436
442
  private rejectDeferredRealize(
437
443
  reason: string,
@@ -448,7 +454,10 @@ export abstract class FluidDataStoreContext
448
454
  }
449
455
 
450
456
  public async realize(): Promise<IFluidDataStoreChannel> {
451
- assert(!this.detachedRuntimeCreation, 0x13d /* "Detached runtime creation on realize()" */);
457
+ assert(
458
+ !this.detachedRuntimeCreation,
459
+ 0x13d /* "Detached runtime creation on realize()" */,
460
+ );
452
461
  if (!this.channelP) {
453
462
  this.channelP = this.realizeCore(this.existing).catch((error) => {
454
463
  const errorWrapped = DataProcessingError.wrapIfUnrecognized(
@@ -719,9 +728,10 @@ export abstract class FluidDataStoreContext
719
728
  *
720
729
  * @param fromPath - The absolute path of the node that added the reference.
721
730
  * @param toPath - The absolute path of the outbound node that is referenced.
731
+ * @param messageTimestampMs - The timestamp of the message that added the reference.
722
732
  */
723
- public addedGCOutboundRoute(fromPath: string, toPath: string) {
724
- this.parentContext.addedGCOutboundRoute(fromPath, toPath);
733
+ public addedGCOutboundRoute(fromPath: string, toPath: string, messageTimestampMs?: number) {
734
+ this.parentContext.addedGCOutboundRoute(fromPath, toPath, messageTimestampMs);
725
735
  }
726
736
 
727
737
  /**
@@ -891,13 +901,17 @@ export abstract class FluidDataStoreContext
891
901
  * Get the summary required when attaching this context's DataStore.
892
902
  * Used for both Container Attach and DataStore Attach.
893
903
  */
894
- public abstract getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
904
+ public abstract getAttachSummary(
905
+ telemetryContext?: ITelemetryContext,
906
+ ): ISummaryTreeWithStats;
895
907
 
896
908
  /**
897
909
  * Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's
898
910
  * outbound routes.
899
911
  */
900
- public abstract getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
912
+ public abstract getAttachGCData(
913
+ telemetryContext?: ITelemetryContext,
914
+ ): IGarbageCollectionData;
901
915
 
902
916
  public abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
903
917
 
@@ -1009,7 +1023,10 @@ export abstract class FluidDataStoreContext
1009
1023
  this.localChangesTelemetryCount--;
1010
1024
  }
1011
1025
 
1012
- public getCreateChildSummarizerNodeFn(id: string, createParam: CreateChildSummarizerNodeParam) {
1026
+ public getCreateChildSummarizerNodeFn(
1027
+ id: string,
1028
+ createParam: CreateChildSummarizerNodeParam,
1029
+ ) {
1013
1030
  return (
1014
1031
  summarizeInternal: SummarizeInternalFn,
1015
1032
  getGCDataFn: (fullGC?: boolean) => Promise<IGarbageCollectionData>,
@@ -1075,7 +1092,10 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
1075
1092
  // Sequence number of the snapshot.
1076
1093
  let sequenceNumber: number | undefined;
1077
1094
  // Check whether we need to fetch the snapshot first to load.
1078
- if (this.snapshotFetchRequired === undefined && this._baseSnapshot?.groupId !== undefined) {
1095
+ if (
1096
+ this.snapshotFetchRequired === undefined &&
1097
+ this._baseSnapshot?.groupId !== undefined
1098
+ ) {
1079
1099
  assert(
1080
1100
  this.blobContents !== undefined,
1081
1101
  0x97a /* Blob contents should be present to evaluate */,
@@ -1143,7 +1163,10 @@ export class RemoteFluidDataStoreContext extends FluidDataStoreContext {
1143
1163
  }
1144
1164
  }
1145
1165
 
1146
- assert(this.pkg !== undefined, 0x8f6 /* The datastore context package should be defined */);
1166
+ assert(
1167
+ this.pkg !== undefined,
1168
+ 0x8f6 /* The datastore context package should be defined */,
1169
+ );
1147
1170
  return {
1148
1171
  pkg: this.pkg,
1149
1172
  isRootDataStore,
@@ -5,12 +5,17 @@
5
5
 
6
6
  import { IDisposable, ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
7
7
  import { assert, Deferred, Lazy } from "@fluidframework/core-utils/internal";
8
- import { ITelemetryLoggerExt, createChildLogger } from "@fluidframework/telemetry-utils/internal";
8
+ import {
9
+ ITelemetryLoggerExt,
10
+ createChildLogger,
11
+ } from "@fluidframework/telemetry-utils/internal";
9
12
 
10
13
  import { FluidDataStoreContext, LocalFluidDataStoreContext } from "./dataStoreContext.js";
11
14
 
12
15
  /** @internal */
13
- export class DataStoreContexts implements Iterable<[string, FluidDataStoreContext]>, IDisposable {
16
+ export class DataStoreContexts
17
+ implements Iterable<[string, FluidDataStoreContext]>, IDisposable
18
+ {
14
19
  private readonly notBoundContexts = new Set<string>();
15
20
 
16
21
  /** Attached and loaded context proxies */
@@ -100,7 +100,10 @@ export abstract class BaseDeltaManagerProxy
100
100
  }
101
101
 
102
102
  constructor(
103
- protected readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
103
+ protected readonly deltaManager: IDeltaManager<
104
+ ISequencedDocumentMessage,
105
+ IDocumentMessage
106
+ >,
104
107
  ) {
105
108
  super();
106
109
 
@@ -192,7 +195,10 @@ export class DeltaManagerSummarizerProxy extends BaseDeltaManagerProxy {
192
195
  private readonly isSummarizerClient: boolean;
193
196
 
194
197
  constructor(
195
- protected readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
198
+ protected readonly deltaManager: IDeltaManager<
199
+ ISequencedDocumentMessage,
200
+ IDocumentMessage
201
+ >,
196
202
  ) {
197
203
  super(deltaManager);
198
204
  this.isSummarizerClient = this.deltaManager.clientDetails.type === summarizerClientType;
@@ -237,7 +243,10 @@ export class DeltaManagerPendingOpsProxy extends BaseDeltaManagerProxy {
237
243
  };
238
244
 
239
245
  constructor(
240
- protected readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
246
+ protected readonly deltaManager: IDeltaManager<
247
+ ISequencedDocumentMessage,
248
+ IDocumentMessage
249
+ >,
241
250
  private readonly pendingStateManager: Pick<
242
251
  PendingStateManager,
243
252
  "minimumPendingMessageSequenceNumber"
@@ -148,9 +148,7 @@ export class DeltaScheduler {
148
148
  numberOfTurns: this.schedulingLog.numberOfTurns,
149
149
  processingTime: formatTick(this.schedulingLog.totalProcessingTime),
150
150
  opsProcessed:
151
- this.schedulingLog.lastSequenceNumber -
152
- this.schedulingLog.firstSequenceNumber +
153
- 1,
151
+ this.schedulingLog.lastSequenceNumber - this.schedulingLog.firstSequenceNumber + 1,
154
152
  batchesProcessed: this.schedulingLog.numberOfBatchesProcessed,
155
153
  duration: formatTick(currentTime - this.schedulingLog.startTime),
156
154
  schedulingCount: this.schedulingCount,
@@ -12,7 +12,10 @@ import {
12
12
  type IGarbageCollectionData,
13
13
  type ITelemetryContext,
14
14
  } from "@fluidframework/runtime-definitions/internal";
15
- import { createResponseError, responseToException } from "@fluidframework/runtime-utils/internal";
15
+ import {
16
+ createResponseError,
17
+ responseToException,
18
+ } from "@fluidframework/runtime-utils/internal";
16
19
  import {
17
20
  ITelemetryLoggerExt,
18
21
  DataProcessingError,
@@ -56,7 +59,10 @@ import {
56
59
  urlToGCNodePath,
57
60
  } from "./gcHelpers.js";
58
61
  import { runGarbageCollection } from "./gcReferenceGraphAlgorithm.js";
59
- import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "./gcSummaryDefinitions.js";
62
+ import {
63
+ IGarbageCollectionSnapshotData,
64
+ IGarbageCollectionState,
65
+ } from "./gcSummaryDefinitions.js";
60
66
  import { GCSummaryStateTracker } from "./gcSummaryStateTracker.js";
61
67
  import { GCTelemetryTracker } from "./gcTelemetry.js";
62
68
  import {
@@ -242,10 +248,7 @@ export class GarbageCollector implements IGarbageCollector {
242
248
  return undefined;
243
249
  }
244
250
 
245
- const snapshotData = await getGCDataFromSnapshot(
246
- gcSnapshotTree,
247
- readAndParseBlob,
248
- );
251
+ const snapshotData = await getGCDataFromSnapshot(gcSnapshotTree, readAndParseBlob);
249
252
 
250
253
  // If the GC version in base snapshot does not match the GC version currently in effect, the GC data
251
254
  // in the snapshot cannot be interpreted correctly. Set everything to undefined except for
@@ -260,10 +263,7 @@ export class GarbageCollector implements IGarbageCollector {
260
263
  }
261
264
  return snapshotData;
262
265
  } catch (error) {
263
- const dpe = DataProcessingError.wrapIfUnrecognized(
264
- error,
265
- "FailedToInitializeGC",
266
- );
266
+ const dpe = DataProcessingError.wrapIfUnrecognized(error, "FailedToInitializeGC");
267
267
  dpe.addTelemetryProperties({
268
268
  gcConfigs: JSON.stringify(this.configs),
269
269
  });
@@ -746,7 +746,7 @@ export class GarbageCollector implements IGarbageCollector {
746
746
  const containerGCMessage: ContainerRuntimeGCMessage = {
747
747
  type: ContainerMessageType.GC,
748
748
  contents,
749
- compatDetails: { behavior: "Ignore" },
749
+ compatDetails: { behavior: "Ignore" }, // DEPRECATED: For temporary back compat only
750
750
  };
751
751
  this.submitMessage(containerGCMessage);
752
752
  return;
@@ -814,14 +814,16 @@ export class GarbageCollector implements IGarbageCollector {
814
814
  */
815
815
  const gcDataSuperSet = concatGarbageCollectionData(previousGCData, currentGCData);
816
816
  const newOutboundRoutesSinceLastRun: string[] = [];
817
- this.newReferencesSinceLastRun.forEach((outboundRoutes: string[], sourceNodeId: string) => {
818
- if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
819
- gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
820
- } else {
821
- gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
822
- }
823
- newOutboundRoutesSinceLastRun.push(...outboundRoutes);
824
- });
817
+ this.newReferencesSinceLastRun.forEach(
818
+ (outboundRoutes: string[], sourceNodeId: string) => {
819
+ if (gcDataSuperSet.gcNodes[sourceNodeId] === undefined) {
820
+ gcDataSuperSet.gcNodes[sourceNodeId] = outboundRoutes;
821
+ } else {
822
+ gcDataSuperSet.gcNodes[sourceNodeId].push(...outboundRoutes);
823
+ }
824
+ newOutboundRoutesSinceLastRun.push(...outboundRoutes);
825
+ },
826
+ );
825
827
 
826
828
  /**
827
829
  * Run GC on the above reference graph starting with root and all new outbound routes. This will generate a
@@ -892,9 +894,14 @@ export class GarbageCollector implements IGarbageCollector {
892
894
  /**
893
895
  * Process a GC message.
894
896
  * @param message - The GC message from the container runtime.
897
+ * @param messageTimestampMs - The timestamp of the message.
895
898
  * @param local - Whether it was send by this client.
896
899
  */
897
- public processMessage(message: ContainerRuntimeGCMessage, local: boolean) {
900
+ public processMessage(
901
+ message: ContainerRuntimeGCMessage,
902
+ messageTimestampMs: number,
903
+ local: boolean,
904
+ ) {
898
905
  const gcMessageType = message.contents.type;
899
906
  switch (gcMessageType) {
900
907
  case GarbageCollectionMessageType.Sweep: {
@@ -909,7 +916,12 @@ export class GarbageCollector implements IGarbageCollector {
909
916
 
910
917
  // Mark the node as referenced to ensure it isn't Swept
911
918
  const tombstonedNodePath = message.contents.nodePath;
912
- this.addedOutboundReference("/", tombstonedNodePath, true /* autorecovery */);
919
+ this.addedOutboundReference(
920
+ "/",
921
+ tombstonedNodePath,
922
+ messageTimestampMs,
923
+ true /* autorecovery */,
924
+ );
913
925
 
914
926
  // In case the cause of the TombstoneLoaded event is incorrect GC Data (i.e. the object is actually reachable),
915
927
  // do fullGC on the next run to get a chance to repair (in the likely case the bug is not deterministic)
@@ -919,10 +931,7 @@ export class GarbageCollector implements IGarbageCollector {
919
931
  }
920
932
  default: {
921
933
  if (
922
- !compatBehaviorAllowsGCMessageType(
923
- gcMessageType,
924
- message.compatDetails?.behavior,
925
- )
934
+ !compatBehaviorAllowsGCMessageType(gcMessageType, message.compatDetails?.behavior)
926
935
  ) {
927
936
  const error = DataProcessingError.create(
928
937
  `Garbage collection message of unknown type ${gcMessageType}`,
@@ -990,7 +999,9 @@ export class GarbageCollector implements IGarbageCollector {
990
999
  request,
991
1000
  headerData,
992
1001
  }: IGCNodeUpdatedProps) {
993
- if (!this.shouldRunGC) {
1002
+ // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
1003
+ // logging as nothing interesting would have happened worth logging.
1004
+ if (!this.shouldRunGC || timestampMs === undefined) {
994
1005
  return;
995
1006
  }
996
1007
 
@@ -1005,8 +1016,7 @@ export class GarbageCollector implements IGarbageCollector {
1005
1016
  this.telemetryTracker.nodeUsed(trackedId, {
1006
1017
  id: fullPath,
1007
1018
  usageType: reason,
1008
- currentReferenceTimestampMs:
1009
- timestampMs ?? this.runtime.getCurrentReferenceTimestampMs(),
1019
+ currentReferenceTimestampMs: timestampMs,
1010
1020
  packagePath,
1011
1021
  completedGCRuns: this.completedRuns,
1012
1022
  isTombstoned,
@@ -1085,7 +1095,7 @@ export class GarbageCollector implements IGarbageCollector {
1085
1095
  type: GarbageCollectionMessageType.TombstoneLoaded,
1086
1096
  nodePath,
1087
1097
  },
1088
- compatDetails: { behavior: "Ignore" },
1098
+ compatDetails: { behavior: "Ignore" }, // DEPRECATED: For temporary back compat only
1089
1099
  };
1090
1100
  this.submitMessage(containerGCMessage);
1091
1101
  }
@@ -1096,9 +1106,15 @@ export class GarbageCollector implements IGarbageCollector {
1096
1106
  *
1097
1107
  * @param fromNodePath - The node from which the reference is added.
1098
1108
  * @param toNodePath - The node to which the reference is added.
1109
+ * @param timestampMs - The timestamp of the message that added the reference.
1099
1110
  * @param autorecovery - This reference is added artificially, for autorecovery. Used for logging.
1100
1111
  */
1101
- public addedOutboundReference(fromNodePath: string, toNodePath: string, autorecovery?: true) {
1112
+ public addedOutboundReference(
1113
+ fromNodePath: string,
1114
+ toNodePath: string,
1115
+ timestampMs: number,
1116
+ autorecovery?: true,
1117
+ ) {
1102
1118
  if (!this.shouldRunGC) {
1103
1119
  return;
1104
1120
  }
@@ -1129,7 +1145,7 @@ export class GarbageCollector implements IGarbageCollector {
1129
1145
  id: toNodePath,
1130
1146
  fromId: fromNodePath,
1131
1147
  usageType: "Revived",
1132
- currentReferenceTimestampMs: this.runtime.getCurrentReferenceTimestampMs(),
1148
+ currentReferenceTimestampMs: timestampMs,
1133
1149
  packagePath: undefined,
1134
1150
  completedGCRuns: this.completedRuns,
1135
1151
  isTombstoned: this.tombstones.includes(trackedId),
@@ -122,7 +122,7 @@ export function generateGCConfigs(
122
122
  !gcEnabled || tombstoneTimeoutMs === undefined
123
123
  ? false
124
124
  : mc.config.getBoolean(runSweepKey) ??
125
- (sweepAllowed && createParams.gcOptions.enableGCSweep === true);
125
+ (sweepAllowed && createParams.gcOptions.enableGCSweep === true);
126
126
  const disableDatastoreSweep =
127
127
  mc.config.getBoolean(disableDatastoreSweepKey) === true ||
128
128
  createParams.gcOptions[gcDisableDataStoreSweepOptionName] === true;
@@ -199,7 +199,11 @@ export function generateGCConfigs(
199
199
  *
200
200
  * If there is no Session Expiry timeout, GC can never guarantee an object won't be revived, so return undefined.
201
201
  */
202
- function computeTombstoneTimeout(sessionExpiryTimeoutMs: number | undefined): number | undefined {
202
+ function computeTombstoneTimeout(
203
+ sessionExpiryTimeoutMs: number | undefined,
204
+ ): number | undefined {
203
205
  const bufferMs = oneDayMs;
204
- return sessionExpiryTimeoutMs && sessionExpiryTimeoutMs + maxSnapshotCacheExpiryMs + bufferMs;
206
+ return (
207
+ sessionExpiryTimeoutMs && sessionExpiryTimeoutMs + maxSnapshotCacheExpiryMs + bufferMs
208
+ );
205
209
  }
@@ -365,9 +365,18 @@ export interface IGarbageCollector {
365
365
  */
366
366
  nodeUpdated(props: IGCNodeUpdatedProps): void;
367
367
  /** Called when a reference is added to a node. Used to identify nodes that were referenced between summaries. */
368
- addedOutboundReference(fromNodePath: string, toNodePath: string, autorecovery?: true): void;
368
+ addedOutboundReference(
369
+ fromNodePath: string,
370
+ toNodePath: string,
371
+ timestampMs: number,
372
+ autorecovery?: true,
373
+ ): void;
369
374
  /** Called to process a garbage collection message. */
370
- processMessage(message: ContainerRuntimeGCMessage, local: boolean): void;
375
+ processMessage(
376
+ message: ContainerRuntimeGCMessage,
377
+ messageTimestampMs: number,
378
+ local: boolean,
379
+ ): void;
371
380
  /** Returns true if this node has been deleted by GC during sweep phase. */
372
381
  isNodeDeleted(nodePath: string): boolean;
373
382
  setConnectionState(connected: boolean, clientId?: string): void;
@@ -383,8 +392,11 @@ export interface IGCNodeUpdatedProps {
383
392
  node: { type: (typeof GCNodeType)["DataStore" | "Blob"]; path: string };
384
393
  /** Whether the node (or a subpath) was loaded or changed. */
385
394
  reason: "Loaded" | "Changed";
386
- /** The op-based timestamp when the node changed, if applicable */
387
- timestampMs?: number;
395
+ /**
396
+ * The op-based timestamp when the node changed. If the update is from receiving an op, this should
397
+ * be the timestamp of the op. If not, this should be the timestamp of the last op processed.
398
+ */
399
+ timestampMs: number | undefined;
388
400
  /** The package path of the node. This may not be available if the node hasn't been loaded yet */
389
401
  packagePath?: readonly string[];
390
402
  /** The original request for loads to preserve it in telemetry */
@@ -78,8 +78,12 @@ export function shouldAllowGcSweep(
78
78
  /**
79
79
  * Sorts the given GC state as per the id of the GC nodes. It also sorts the outbound routes array of each node.
80
80
  */
81
- export function generateSortedGCState(gcState: IGarbageCollectionState): IGarbageCollectionState {
82
- const sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(gcState.gcNodes);
81
+ export function generateSortedGCState(
82
+ gcState: IGarbageCollectionState,
83
+ ): IGarbageCollectionState {
84
+ const sortableArray: [string, IGarbageCollectionNodeData][] = Object.entries(
85
+ gcState.gcNodes,
86
+ );
83
87
  sortableArray.sort(([a], [b]) => a.localeCompare(b));
84
88
  const sortedGCState: IGarbageCollectionState = { gcNodes: {} };
85
89
  for (const [nodeId, nodeData] of sortableArray) {
@@ -18,7 +18,10 @@ import { IRefreshSummaryResult } from "../summary/index.js";
18
18
 
19
19
  import { IGCStats, IGarbageCollectorConfigs } from "./gcDefinitions.js";
20
20
  import { generateSortedGCState } from "./gcHelpers.js";
21
- import { IGarbageCollectionSnapshotData, IGarbageCollectionState } from "./gcSummaryDefinitions.js";
21
+ import {
22
+ IGarbageCollectionSnapshotData,
23
+ IGarbageCollectionState,
24
+ } from "./gcSummaryDefinitions.js";
22
25
 
23
26
  export const gcStateBlobKey = `${gcBlobPrefix}_root`;
24
27
 
@@ -63,7 +63,7 @@ interface INodeUsageProps extends ICommonProps {
63
63
  /** The full path (in GC Path format) to the node in question */
64
64
  id: string;
65
65
  /** Latest timestamp received from the server, as a baseline for computing GC state/age */
66
- currentReferenceTimestampMs: number | undefined;
66
+ currentReferenceTimestampMs: number;
67
67
  /** The package path of the node. This may not be available if the node hasn't been loaded yet */
68
68
  packagePath: readonly string[] | undefined;
69
69
  /** In case of Revived - what node added the reference? */
@@ -165,12 +165,6 @@ export class GCTelemetryTracker {
165
165
  ...otherNodeUsageProps
166
166
  }: INodeUsageProps,
167
167
  ) {
168
- // If there is no reference timestamp to work with, no ops have been processed after creation. If so, skip
169
- // logging as nothing interesting would have happened worth logging.
170
- if (currentReferenceTimestampMs === undefined) {
171
- return;
172
- }
173
-
174
168
  // Note: For SubDataStore Load usage, trackedId will be the DataStore's id, not the full path in question.
175
169
  // This is necessary because the SubDataStore path may be unrecognized by GC (if suited for a custom request handler)
176
170
  const nodeStateTracker = this.getNodeStateTracker(trackedId);
@@ -390,8 +384,7 @@ export class GCTelemetryTracker {
390
384
  */
391
385
  const nodeStateTracker = this.getNodeStateTracker(detailedProps.trackedId); // Note: This is never SubDataStore path
392
386
  const active =
393
- nodeStateTracker === undefined ||
394
- nodeStateTracker.state === UnreferencedState.Active;
387
+ nodeStateTracker === undefined || nodeStateTracker.state === UnreferencedState.Active;
395
388
  if ((usageType === "Revived") === active) {
396
389
  const pkg = await this.getNodePackagePath(eventProps.id.value);
397
390
  const fromPkg = eventProps.fromId
package/src/index.ts CHANGED
@@ -25,7 +25,6 @@ export {
25
25
  } from "./containerRuntime.js";
26
26
  export {
27
27
  ContainerMessageType,
28
- ContainerRuntimeMessage,
29
28
  IContainerRuntimeMessageCompatDetails,
30
29
  CompatModeBehavior,
31
30
  RecentlyAddedContainerRuntimeMessageDetails,
@@ -60,6 +60,7 @@ export enum ContainerMessageType {
60
60
  /**
61
61
  * How should an older client handle an unrecognized remote op type?
62
62
  *
63
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
63
64
  * @internal
64
65
  */
65
66
  export type CompatModeBehavior =
@@ -71,6 +72,7 @@ export type CompatModeBehavior =
71
72
  /**
72
73
  * All the info an older client would need to know how to handle an unrecognized remote op type
73
74
  *
75
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
74
76
  * @internal
75
77
  */
76
78
  export interface IContainerRuntimeMessageCompatDetails {
@@ -85,8 +87,7 @@ export interface IContainerRuntimeMessageCompatDetails {
85
87
  * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
86
88
  * This way stringified values can be compared.
87
89
  */
88
- interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents>
89
- extends Partial<RecentlyAddedContainerRuntimeMessageDetails> {
90
+ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TContents> {
90
91
  /** Type of the op, within the ContainerRuntime's domain */
91
92
  type: TType;
92
93
  /** Domain-specific contents, interpreted according to the type */
@@ -95,6 +96,7 @@ interface TypedContainerRuntimeMessage<TType extends ContainerMessageType, TCont
95
96
 
96
97
  /**
97
98
  * Additional details expected for any recently added message.
99
+ * @deprecated The utility of a mechanism to handle unknown messages is outweighed by the nuance required to get it right.
98
100
  * @internal
99
101
  */
100
102
  export interface RecentlyAddedContainerRuntimeMessageDetails {
@@ -137,7 +139,9 @@ export type ContainerRuntimeIdAllocationMessage = TypedContainerRuntimeMessage<
137
139
  export type ContainerRuntimeGCMessage = TypedContainerRuntimeMessage<
138
140
  ContainerMessageType.GC,
139
141
  GarbageCollectionMessage
140
- >;
142
+ > &
143
+ // While deprecating: GC messages may still contain compat details for now
144
+ Partial<RecentlyAddedContainerRuntimeMessageDetails>;
141
145
  export type ContainerRuntimeDocumentSchemaMessage = TypedContainerRuntimeMessage<
142
146
  ContainerMessageType.DocumentSchemaChange,
143
147
  IDocumentSchemaChangeMessage
@@ -232,23 +236,3 @@ export type InboundSequencedContainerRuntimeMessageOrSystemMessage =
232
236
  */
233
237
  export type InboundSequencedRecentlyAddedContainerRuntimeMessage = ISequencedDocumentMessage &
234
238
  Partial<RecentlyAddedContainerRuntimeMessageDetails>;
235
-
236
- /**
237
- * The unpacked runtime message / details to be handled or dispatched by the ContainerRuntime
238
- *
239
- * IMPORTANT: when creating one to be serialized, set the properties in the order they appear here.
240
- * This way stringified values can be compared.
241
- *
242
- * @deprecated this is an internal type which should not be used outside of the package.
243
- * Internally, it is superseded by `TypedContainerRuntimeMessage`.
244
- *
245
- * @internal
246
- */
247
- export interface ContainerRuntimeMessage {
248
- /** Type of the op, within the ContainerRuntime's domain */
249
- type: ContainerMessageType;
250
- /** Domain-specific contents, interpreted according to the type */
251
- contents: any;
252
- /** Info describing how to handle this op in case the type is unrecognized (default: fail to process) */
253
- compatDetails?: IContainerRuntimeMessageCompatDetails;
254
- }
@@ -10,4 +10,8 @@ export { OpCompressor } from "./opCompressor.js";
10
10
  export { OpDecompressor } from "./opDecompressor.js";
11
11
  export { OpSplitter, splitOp, isChunkedMessage } from "./opSplitter.js";
12
12
  export { RemoteMessageProcessor, unpackRuntimeMessage } from "./remoteMessageProcessor.js";
13
- export { OpGroupingManager, OpGroupingManagerConfig, isGroupedBatch } from "./opGroupingManager.js";
13
+ export {
14
+ OpGroupingManager,
15
+ OpGroupingManagerConfig,
16
+ isGroupedBatch,
17
+ } from "./opGroupingManager.js";
@@ -65,8 +65,7 @@ export class OpDecompressor {
65
65
  IsoBuffer.from(
66
66
  (message.contents as IPackedContentsContents).packedContents,
67
67
  "base64",
68
- ).toString("base64") ===
69
- (message.contents as IPackedContentsContents).packedContents
68
+ ).toString("base64") === (message.contents as IPackedContentsContents).packedContents
70
69
  ) {
71
70
  this.logger.sendTelemetryEvent({
72
71
  eventName: "LegacyCompression",
@@ -139,10 +138,7 @@ export class OpDecompressor {
139
138
 
140
139
  if (batchMetadata === false || this.isSingleMessageBatch) {
141
140
  // End of compressed batch
142
- const returnMessage = newMessage(
143
- message,
144
- this.rootMessageContents[this.processedCount],
145
- );
141
+ const returnMessage = newMessage(message, this.rootMessageContents[this.processedCount]);
146
142
 
147
143
  this.activeBatch = false;
148
144
  this.isSingleMessageBatch = false;
@@ -73,10 +73,7 @@ export class OpGroupingManager {
73
73
  if (message.metadata) {
74
74
  const keys = Object.keys(message.metadata);
75
75
  assert(keys.length < 2, 0x5dd /* cannot group ops with metadata */);
76
- assert(
77
- keys.length === 0 || keys[0] === "batch",
78
- 0x5de /* unexpected op metadata */,
79
- );
76
+ assert(keys.length === 0 || keys[0] === "batch", 0x5de /* unexpected op metadata */);
80
77
  }
81
78
  }
82
79
 
@@ -53,7 +53,9 @@ export class OpSplitter {
53
53
  }
54
54
 
55
55
  public get isBatchChunkingEnabled(): boolean {
56
- return this.chunkSizeInBytes < Number.POSITIVE_INFINITY && this.submitBatchFn !== undefined;
56
+ return (
57
+ this.chunkSizeInBytes < Number.POSITIVE_INFINITY && this.submitBatchFn !== undefined
58
+ );
57
59
  }
58
60
 
59
61
  public get chunks(): ReadonlyMap<string, string[]> {
@@ -272,7 +274,8 @@ export const splitOp = (
272
274
  );
273
275
 
274
276
  const contentLength = op.contents.length;
275
- const chunkCount = Math.floor((contentLength - 1) / chunkSizeInBytes) + 1 + (extraOp ? 1 : 0);
277
+ const chunkCount =
278
+ Math.floor((contentLength - 1) / chunkSizeInBytes) + 1 + (extraOp ? 1 : 0);
276
279
  let offset = 0;
277
280
  for (let chunkId = 1; chunkId <= chunkCount; chunkId++) {
278
281
  const chunk: IChunkedOp = {
@@ -306,7 +309,10 @@ export const splitOp = (
306
309
  );
307
310
  }
308
311
 
309
- assert(offset >= contentLength, 0x58c /* Content offset equal or larger than content length */);
312
+ assert(
313
+ offset >= contentLength,
314
+ 0x58c /* Content offset equal or larger than content length */,
315
+ );
310
316
  assert(chunks.length === chunkCount, 0x5a5 /* Expected number of chunks */);
311
317
  return chunks;
312
318
  };
@@ -382,10 +382,7 @@ export class Outbox {
382
382
 
383
383
  this.params.legacySendBatchFn(batch);
384
384
  } else {
385
- assert(
386
- batch.referenceSequenceNumber !== undefined,
387
- 0x58e /* Batch must not be empty */,
388
- );
385
+ assert(batch.referenceSequenceNumber !== undefined, 0x58e /* Batch must not be empty */);
389
386
  this.params.submitBatchFn(
390
387
  batch.content.map((message) => ({
391
388
  contents: message.contents,
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.0.0-dev-rc.5.0.0.271717";
9
+ export const pkgVersion = "2.0.0-dev-rc.5.0.0.272889";