@fluidframework/container-runtime 2.41.0-338401 → 2.42.0

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 (161) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/channelCollection.d.ts +1 -1
  4. package/dist/channelCollection.d.ts.map +1 -1
  5. package/dist/channelCollection.js +4 -4
  6. package/dist/channelCollection.js.map +1 -1
  7. package/dist/compatUtils.d.ts +22 -1
  8. package/dist/compatUtils.d.ts.map +1 -1
  9. package/dist/compatUtils.js +109 -7
  10. package/dist/compatUtils.js.map +1 -1
  11. package/dist/containerRuntime.d.ts +67 -28
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +332 -186
  14. package/dist/containerRuntime.js.map +1 -1
  15. package/dist/dataStore.d.ts.map +1 -1
  16. package/dist/dataStore.js +5 -0
  17. package/dist/dataStore.js.map +1 -1
  18. package/dist/gc/garbageCollection.d.ts.map +1 -1
  19. package/dist/gc/garbageCollection.js +2 -0
  20. package/dist/gc/garbageCollection.js.map +1 -1
  21. package/dist/gc/gcDefinitions.d.ts +1 -1
  22. package/dist/gc/gcDefinitions.d.ts.map +1 -1
  23. package/dist/gc/gcDefinitions.js.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/messageTypes.d.ts +5 -4
  28. package/dist/messageTypes.d.ts.map +1 -1
  29. package/dist/messageTypes.js.map +1 -1
  30. package/dist/metadata.d.ts +1 -1
  31. package/dist/metadata.d.ts.map +1 -1
  32. package/dist/metadata.js.map +1 -1
  33. package/dist/opLifecycle/batchManager.d.ts +4 -0
  34. package/dist/opLifecycle/batchManager.d.ts.map +1 -1
  35. package/dist/opLifecycle/batchManager.js +7 -0
  36. package/dist/opLifecycle/batchManager.js.map +1 -1
  37. package/dist/opLifecycle/definitions.d.ts +6 -5
  38. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  39. package/dist/opLifecycle/definitions.js.map +1 -1
  40. package/dist/opLifecycle/index.d.ts +1 -1
  41. package/dist/opLifecycle/index.d.ts.map +1 -1
  42. package/dist/opLifecycle/index.js.map +1 -1
  43. package/dist/opLifecycle/opGroupingManager.d.ts +9 -0
  44. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  45. package/dist/opLifecycle/opGroupingManager.js +6 -4
  46. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  47. package/dist/opLifecycle/opSerialization.d.ts +2 -1
  48. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  49. package/dist/opLifecycle/opSerialization.js.map +1 -1
  50. package/dist/opLifecycle/outbox.d.ts +1 -0
  51. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  52. package/dist/opLifecycle/outbox.js +6 -1
  53. package/dist/opLifecycle/outbox.js.map +1 -1
  54. package/dist/packageVersion.d.ts +1 -1
  55. package/dist/packageVersion.d.ts.map +1 -1
  56. package/dist/packageVersion.js +1 -1
  57. package/dist/packageVersion.js.map +1 -1
  58. package/dist/pendingStateManager.d.ts +22 -5
  59. package/dist/pendingStateManager.d.ts.map +1 -1
  60. package/dist/pendingStateManager.js +34 -11
  61. package/dist/pendingStateManager.js.map +1 -1
  62. package/dist/runCounter.d.ts.map +1 -1
  63. package/dist/runCounter.js +1 -1
  64. package/dist/runCounter.js.map +1 -1
  65. package/dist/summary/documentSchema.d.ts +42 -18
  66. package/dist/summary/documentSchema.d.ts.map +1 -1
  67. package/dist/summary/documentSchema.js +62 -52
  68. package/dist/summary/documentSchema.js.map +1 -1
  69. package/dist/summary/index.d.ts +1 -1
  70. package/dist/summary/index.d.ts.map +1 -1
  71. package/dist/summary/index.js.map +1 -1
  72. package/lib/channelCollection.d.ts +1 -1
  73. package/lib/channelCollection.d.ts.map +1 -1
  74. package/lib/channelCollection.js +4 -4
  75. package/lib/channelCollection.js.map +1 -1
  76. package/lib/compatUtils.d.ts +22 -1
  77. package/lib/compatUtils.d.ts.map +1 -1
  78. package/lib/compatUtils.js +102 -3
  79. package/lib/compatUtils.js.map +1 -1
  80. package/lib/containerRuntime.d.ts +67 -28
  81. package/lib/containerRuntime.d.ts.map +1 -1
  82. package/lib/containerRuntime.js +333 -188
  83. package/lib/containerRuntime.js.map +1 -1
  84. package/lib/dataStore.d.ts.map +1 -1
  85. package/lib/dataStore.js +5 -0
  86. package/lib/dataStore.js.map +1 -1
  87. package/lib/gc/garbageCollection.d.ts.map +1 -1
  88. package/lib/gc/garbageCollection.js +2 -0
  89. package/lib/gc/garbageCollection.js.map +1 -1
  90. package/lib/gc/gcDefinitions.d.ts +1 -1
  91. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  92. package/lib/gc/gcDefinitions.js.map +1 -1
  93. package/lib/index.d.ts +1 -1
  94. package/lib/index.d.ts.map +1 -1
  95. package/lib/index.js.map +1 -1
  96. package/lib/messageTypes.d.ts +5 -4
  97. package/lib/messageTypes.d.ts.map +1 -1
  98. package/lib/messageTypes.js.map +1 -1
  99. package/lib/metadata.d.ts +1 -1
  100. package/lib/metadata.d.ts.map +1 -1
  101. package/lib/metadata.js.map +1 -1
  102. package/lib/opLifecycle/batchManager.d.ts +4 -0
  103. package/lib/opLifecycle/batchManager.d.ts.map +1 -1
  104. package/lib/opLifecycle/batchManager.js +7 -0
  105. package/lib/opLifecycle/batchManager.js.map +1 -1
  106. package/lib/opLifecycle/definitions.d.ts +6 -5
  107. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  108. package/lib/opLifecycle/definitions.js.map +1 -1
  109. package/lib/opLifecycle/index.d.ts +1 -1
  110. package/lib/opLifecycle/index.d.ts.map +1 -1
  111. package/lib/opLifecycle/index.js.map +1 -1
  112. package/lib/opLifecycle/opGroupingManager.d.ts +9 -0
  113. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  114. package/lib/opLifecycle/opGroupingManager.js +6 -4
  115. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  116. package/lib/opLifecycle/opSerialization.d.ts +2 -1
  117. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  118. package/lib/opLifecycle/opSerialization.js.map +1 -1
  119. package/lib/opLifecycle/outbox.d.ts +1 -0
  120. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  121. package/lib/opLifecycle/outbox.js +6 -1
  122. package/lib/opLifecycle/outbox.js.map +1 -1
  123. package/lib/packageVersion.d.ts +1 -1
  124. package/lib/packageVersion.d.ts.map +1 -1
  125. package/lib/packageVersion.js +1 -1
  126. package/lib/packageVersion.js.map +1 -1
  127. package/lib/pendingStateManager.d.ts +22 -5
  128. package/lib/pendingStateManager.d.ts.map +1 -1
  129. package/lib/pendingStateManager.js +34 -11
  130. package/lib/pendingStateManager.js.map +1 -1
  131. package/lib/runCounter.d.ts.map +1 -1
  132. package/lib/runCounter.js +1 -1
  133. package/lib/runCounter.js.map +1 -1
  134. package/lib/summary/documentSchema.d.ts +42 -18
  135. package/lib/summary/documentSchema.d.ts.map +1 -1
  136. package/lib/summary/documentSchema.js +62 -52
  137. package/lib/summary/documentSchema.js.map +1 -1
  138. package/lib/summary/index.d.ts +1 -1
  139. package/lib/summary/index.d.ts.map +1 -1
  140. package/lib/summary/index.js.map +1 -1
  141. package/package.json +19 -19
  142. package/src/channelCollection.ts +4 -4
  143. package/src/compatUtils.ts +145 -10
  144. package/src/containerRuntime.ts +472 -225
  145. package/src/dataStore.ts +7 -0
  146. package/src/gc/garbageCollection.ts +2 -0
  147. package/src/gc/gcDefinitions.ts +1 -1
  148. package/src/index.ts +2 -1
  149. package/src/messageTypes.ts +12 -5
  150. package/src/metadata.ts +1 -1
  151. package/src/opLifecycle/batchManager.ts +8 -0
  152. package/src/opLifecycle/definitions.ts +7 -3
  153. package/src/opLifecycle/index.ts +1 -0
  154. package/src/opLifecycle/opGroupingManager.ts +17 -4
  155. package/src/opLifecycle/opSerialization.ts +6 -1
  156. package/src/opLifecycle/outbox.ts +8 -1
  157. package/src/packageVersion.ts +1 -1
  158. package/src/pendingStateManager.ts +64 -20
  159. package/src/runCounter.ts +4 -1
  160. package/src/summary/documentSchema.ts +111 -86
  161. package/src/summary/index.ts +2 -1
@@ -3,8 +3,10 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
+ import { assert } from "@fluidframework/core-utils/internal";
6
7
  import { FlushMode } from "@fluidframework/runtime-definitions/internal";
7
- import { compare, gte, lte, valid } from "semver-ts";
8
+ import { UsageError } from "@fluidframework/telemetry-utils/internal";
9
+ import { compare, gt, gte, lte, valid } from "semver-ts";
8
10
 
9
11
  import {
10
12
  disabledCompressionConfig,
@@ -78,6 +80,13 @@ export type ConfigMap<T extends Record<string, unknown>> = {
78
80
  };
79
81
  };
80
82
 
83
+ /**
84
+ * Generic type for runtimeOptionsAffectingDocSchemaConfigValidationMap
85
+ */
86
+ export type ConfigValidationMap<T extends Record<string, unknown>> = {
87
+ [K in keyof T]-?: (configValue: T[K]) => SemanticVersion | undefined;
88
+ };
89
+
81
90
  /**
82
91
  * Subset of the {@link ContainerRuntimeOptionsInternal} properties which
83
92
  * affect {@link IDocumentSchemaFeatures}.
@@ -119,11 +128,11 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
119
128
  enableGroupedBatching: {
120
129
  "1.0.0": false,
121
130
  "2.0.0-defaults": true,
122
- } as const,
131
+ },
123
132
  compressionOptions: {
124
133
  "1.0.0": disabledCompressionConfig,
125
134
  "2.0.0-defaults": enabledCompressionConfig,
126
- } as const,
135
+ },
127
136
  enableRuntimeIdCompressor: {
128
137
  // For IdCompressorMode, `undefined` represents a logical state (off).
129
138
  // However, to satisfy the Required<> constraint while
@@ -135,7 +144,7 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
135
144
  // Therefore, we will require customers to explicitly enable it. We
136
145
  // are keeping it as a DocSchema affecting option for now as this may
137
146
  // change in the future.
138
- } as const,
147
+ },
139
148
  explicitSchemaControl: {
140
149
  "1.0.0": false,
141
150
  // This option's intention is to prevent 1.x clients from joining sessions
@@ -149,34 +158,66 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
149
158
  // Only enable as a default when `minVersionForCollab` is specified at
150
159
  // 2.0.0+.
151
160
  "2.0.0": true,
152
- } as const,
161
+ },
153
162
  flushMode: {
154
163
  // Note: 1.x clients are compatible with TurnBased flushing, but here we elect to remain on Immediate flush mode
155
164
  // as a work-around for inability to send batches larger than 1Mb. Immediate flushing keeps batches smaller as
156
165
  // fewer messages will be included per flush.
157
166
  "1.0.0": FlushMode.Immediate,
158
167
  "2.0.0-defaults": FlushMode.TurnBased,
159
- } as const,
168
+ },
160
169
  gcOptions: {
161
170
  "1.0.0": {},
162
171
  // Although sweep is supported in 2.x, it is disabled by default until minVersionForCollab>=3.0.0 to be extra safe.
163
172
  "3.0.0": { enableGCSweep: true },
164
- } as const,
173
+ },
165
174
  createBlobPayloadPending: {
166
175
  // This feature is new and disabled by default. In the future we will enable it by default, but we have not
167
176
  // closed on the version where that will happen yet. Probably a .10 release since blob functionality is not
168
177
  // exposed on the `@public` API surface.
169
178
  "1.0.0": undefined,
170
- } as const,
179
+ },
171
180
  } as const satisfies ConfigMap<RuntimeOptionsAffectingDocSchema>;
172
181
 
182
+ const runtimeOptionsAffectingDocSchemaConfigValidationMap = {
183
+ enableGroupedBatching: configValueToMinVersionForCollab([
184
+ [false, "1.0.0"],
185
+ [true, "2.0.0-defaults"],
186
+ ]),
187
+ compressionOptions: configValueToMinVersionForCollab([
188
+ [{ ...disabledCompressionConfig }, "1.0.0"],
189
+ [{ ...enabledCompressionConfig }, "2.0.0-defaults"],
190
+ ]),
191
+ enableRuntimeIdCompressor: configValueToMinVersionForCollab([
192
+ [undefined, "1.0.0"],
193
+ ["on", "2.0.0-defaults"],
194
+ ["delayed", "2.0.0-defaults"],
195
+ ]),
196
+ explicitSchemaControl: configValueToMinVersionForCollab([
197
+ [false, "1.0.0"],
198
+ [true, "2.0.0-defaults"],
199
+ ]),
200
+ flushMode: configValueToMinVersionForCollab([
201
+ [FlushMode.Immediate, "1.0.0"],
202
+ [FlushMode.TurnBased, "2.0.0-defaults"],
203
+ ]),
204
+ gcOptions: configValueToMinVersionForCollab([
205
+ [{ enableGCSweep: undefined }, "1.0.0"],
206
+ [{ enableGCSweep: true }, "2.0.0-defaults"],
207
+ ]),
208
+ createBlobPayloadPending: configValueToMinVersionForCollab([
209
+ [undefined, "1.0.0"],
210
+ [true, "2.40.0"],
211
+ ]),
212
+ } as const satisfies ConfigValidationMap<RuntimeOptionsAffectingDocSchema>;
213
+
173
214
  /**
174
215
  * Returns the default RuntimeOptionsAffectingDocSchema configuration for a given minVersionForCollab.
175
216
  */
176
217
  export function getMinVersionForCollabDefaults(
177
218
  minVersionForCollab: MinimumVersionForCollab,
178
219
  ): RuntimeOptionsAffectingDocSchema {
179
- return getConfigsForCompatMode(
220
+ return getConfigsForMinVersionForCollab(
180
221
  minVersionForCollab,
181
222
  runtimeOptionsAffectingDocSchemaConfigMap,
182
223
  // This is a bad cast away from Partial that getConfigsForCompatMode provides.
@@ -187,7 +228,7 @@ export function getMinVersionForCollabDefaults(
187
228
  /**
188
229
  * Returns a default configuration given minVersionForCollab and configuration version map.
189
230
  */
190
- export function getConfigsForCompatMode<T extends Record<SemanticVersion, unknown>>(
231
+ export function getConfigsForMinVersionForCollab<T extends Record<SemanticVersion, unknown>>(
191
232
  minVersionForCollab: SemanticVersion,
192
233
  configMap: ConfigMap<T>,
193
234
  ): Partial<T> {
@@ -226,3 +267,97 @@ export function isValidMinVersionForCollab(
226
267
  lte(minVersionForCollab, pkgVersion)
227
268
  );
228
269
  }
270
+
271
+ /**
272
+ * Validates if the runtime options passed in from the user are compatible with the minVersionForCollab.
273
+ * For example, if a user sets the `enableGroupedBatching` option to true, but the minVersionForCollab
274
+ * is set to "1.0.0", then we should throw a UsageError since 1.x clients do not support batching.
275
+ * */
276
+ export function validateRuntimeOptions(
277
+ minVersionForCollab: MinimumVersionForCollab,
278
+ runtimeOptions: Partial<ContainerRuntimeOptionsInternal>,
279
+ ): void {
280
+ getValidationForRuntimeOptions<RuntimeOptionsAffectingDocSchema>(
281
+ minVersionForCollab,
282
+ runtimeOptions as Partial<RuntimeOptionsAffectingDocSchema>,
283
+ runtimeOptionsAffectingDocSchemaConfigValidationMap,
284
+ );
285
+ }
286
+
287
+ /**
288
+ * Generic function to validate runtime options against the minVersionForCollab.
289
+ */
290
+ export function getValidationForRuntimeOptions<T extends Record<string, unknown>>(
291
+ minVersionForCollab: SemanticVersion,
292
+ runtimeOptions: Partial<T>,
293
+ validationMap: ConfigValidationMap<T>,
294
+ ): void {
295
+ if (minVersionForCollab === defaultMinVersionForCollab) {
296
+ // If the minVersionForCollab is set to the default value, then we will not validate the runtime options
297
+ // This is to avoid disruption to users who have not yet set the minVersionForCollab value explicitly.
298
+ return;
299
+ }
300
+ // Iterate through each runtime option passed in by the user
301
+ for (const [passedRuntimeOption, passedRuntimeOptionValue] of Object.entries(
302
+ runtimeOptions,
303
+ ) as [keyof T & string, T[keyof T & string]][]) {
304
+ // Skip if passedRuntimeOption is not in validation map
305
+ if (!(passedRuntimeOption in validationMap)) {
306
+ continue;
307
+ }
308
+
309
+ const requiredVersion = validationMap[passedRuntimeOption](passedRuntimeOptionValue);
310
+ if (requiredVersion !== undefined && gt(requiredVersion, minVersionForCollab)) {
311
+ throw new UsageError(
312
+ `Runtime option ${passedRuntimeOption}:${JSON.stringify(passedRuntimeOptionValue)} requires ` +
313
+ `runtime version ${requiredVersion}. Please update minVersionForCollab ` +
314
+ `(currently ${minVersionForCollab}) to ${requiredVersion} or later to proceed.`,
315
+ );
316
+ }
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Helper function to map ContainerRuntimeOptionsInternal config values to
322
+ * minVersionForCollab in {@link runtimeOptionsAffectingDocSchemaConfigValidationMap}.
323
+ */
324
+ export function configValueToMinVersionForCollab<
325
+ T extends string | number | boolean | undefined | object,
326
+ Arr extends readonly [T, SemanticVersion][],
327
+ >(configToMinVer: Arr): (configValue: T) => SemanticVersion | undefined {
328
+ const configValueToRequiredVersionMap = new Map(configToMinVer);
329
+ return (configValue: T) => {
330
+ // If the configValue is not an object then we can get the version required directly from the map.
331
+ if (typeof configValue !== "object") {
332
+ return configValueToRequiredVersionMap.get(configValue);
333
+ }
334
+ // When the input `configValue` is an object, this logic determines the minimum runtime version it requires.
335
+ // It iterates through each entry in `configValueToRequiredVersionMap`. If `possibleConfigValue` shares at
336
+ // least one key-value pair with the input `configValue`, its associated `versionRequired` is collected into
337
+ // `matchingVersions`. After checking all entries, the highest among the collected versions is returned.
338
+ // This represents the overall minimum version required to support the features implied by the input `configValue`.
339
+ const matchingVersions: SemanticVersion[] = [];
340
+ for (const [
341
+ possibleConfigValue,
342
+ versionRequired,
343
+ ] of configValueToRequiredVersionMap.entries()) {
344
+ assert(
345
+ typeof possibleConfigValue == "object",
346
+ 0xbb9 /* possibleConfigValue should be an object */,
347
+ );
348
+ // Check if `possibleConfigValue` and the input `configValue` share at least one
349
+ // common key-value pair. If they do, the `versionRequired` for this `possibleConfigValue`
350
+ // is added to `matchingVersions`.
351
+ if (Object.entries(possibleConfigValue).some(([k, v]) => configValue[k] === v)) {
352
+ matchingVersions.push(versionRequired);
353
+ }
354
+ }
355
+ if (matchingVersions.length > 0) {
356
+ // Return the latest minVersionForCollab among all matches.
357
+ return matchingVersions.sort((a, b) => compare(b, a))[0];
358
+ }
359
+ // If no matches then we return undefined. This means that the config value passed in
360
+ // does not require a specific minVersionForCollab to be valid.
361
+ return undefined;
362
+ };
363
+ }