@fluidframework/container-runtime 2.41.0 → 2.43.0-343119

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 (136) hide show
  1. package/CHANGELOG.md +4 -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 +24 -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 +36 -15
  12. package/dist/containerRuntime.d.ts.map +1 -1
  13. package/dist/containerRuntime.js +186 -71
  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 +2 -2
  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/definitions.d.ts +6 -5
  34. package/dist/opLifecycle/definitions.d.ts.map +1 -1
  35. package/dist/opLifecycle/definitions.js.map +1 -1
  36. package/dist/opLifecycle/index.d.ts +1 -1
  37. package/dist/opLifecycle/index.d.ts.map +1 -1
  38. package/dist/opLifecycle/index.js.map +1 -1
  39. package/dist/opLifecycle/opGroupingManager.d.ts +9 -0
  40. package/dist/opLifecycle/opGroupingManager.d.ts.map +1 -1
  41. package/dist/opLifecycle/opGroupingManager.js +6 -4
  42. package/dist/opLifecycle/opGroupingManager.js.map +1 -1
  43. package/dist/opLifecycle/opSerialization.d.ts +2 -1
  44. package/dist/opLifecycle/opSerialization.d.ts.map +1 -1
  45. package/dist/opLifecycle/opSerialization.js.map +1 -1
  46. package/dist/packageVersion.d.ts +1 -1
  47. package/dist/packageVersion.d.ts.map +1 -1
  48. package/dist/packageVersion.js +1 -1
  49. package/dist/packageVersion.js.map +1 -1
  50. package/dist/pendingStateManager.d.ts +18 -5
  51. package/dist/pendingStateManager.d.ts.map +1 -1
  52. package/dist/pendingStateManager.js +20 -13
  53. package/dist/pendingStateManager.js.map +1 -1
  54. package/dist/summary/documentSchema.d.ts +79 -16
  55. package/dist/summary/documentSchema.d.ts.map +1 -1
  56. package/dist/summary/documentSchema.js +119 -53
  57. package/dist/summary/documentSchema.js.map +1 -1
  58. package/dist/summary/index.d.ts +1 -1
  59. package/dist/summary/index.d.ts.map +1 -1
  60. package/dist/summary/index.js.map +1 -1
  61. package/lib/channelCollection.d.ts +1 -1
  62. package/lib/channelCollection.d.ts.map +1 -1
  63. package/lib/channelCollection.js +4 -4
  64. package/lib/channelCollection.js.map +1 -1
  65. package/lib/compatUtils.d.ts +24 -1
  66. package/lib/compatUtils.d.ts.map +1 -1
  67. package/lib/compatUtils.js +102 -3
  68. package/lib/compatUtils.js.map +1 -1
  69. package/lib/containerRuntime.d.ts +36 -15
  70. package/lib/containerRuntime.d.ts.map +1 -1
  71. package/lib/containerRuntime.js +188 -73
  72. package/lib/containerRuntime.js.map +1 -1
  73. package/lib/dataStore.d.ts.map +1 -1
  74. package/lib/dataStore.js +5 -0
  75. package/lib/dataStore.js.map +1 -1
  76. package/lib/gc/garbageCollection.d.ts.map +1 -1
  77. package/lib/gc/garbageCollection.js +2 -0
  78. package/lib/gc/garbageCollection.js.map +1 -1
  79. package/lib/gc/gcDefinitions.d.ts +1 -1
  80. package/lib/gc/gcDefinitions.d.ts.map +1 -1
  81. package/lib/gc/gcDefinitions.js.map +1 -1
  82. package/lib/index.d.ts +2 -2
  83. package/lib/index.d.ts.map +1 -1
  84. package/lib/index.js.map +1 -1
  85. package/lib/messageTypes.d.ts +5 -4
  86. package/lib/messageTypes.d.ts.map +1 -1
  87. package/lib/messageTypes.js.map +1 -1
  88. package/lib/metadata.d.ts +1 -1
  89. package/lib/metadata.d.ts.map +1 -1
  90. package/lib/metadata.js.map +1 -1
  91. package/lib/opLifecycle/definitions.d.ts +6 -5
  92. package/lib/opLifecycle/definitions.d.ts.map +1 -1
  93. package/lib/opLifecycle/definitions.js.map +1 -1
  94. package/lib/opLifecycle/index.d.ts +1 -1
  95. package/lib/opLifecycle/index.d.ts.map +1 -1
  96. package/lib/opLifecycle/index.js.map +1 -1
  97. package/lib/opLifecycle/opGroupingManager.d.ts +9 -0
  98. package/lib/opLifecycle/opGroupingManager.d.ts.map +1 -1
  99. package/lib/opLifecycle/opGroupingManager.js +6 -4
  100. package/lib/opLifecycle/opGroupingManager.js.map +1 -1
  101. package/lib/opLifecycle/opSerialization.d.ts +2 -1
  102. package/lib/opLifecycle/opSerialization.d.ts.map +1 -1
  103. package/lib/opLifecycle/opSerialization.js.map +1 -1
  104. package/lib/packageVersion.d.ts +1 -1
  105. package/lib/packageVersion.d.ts.map +1 -1
  106. package/lib/packageVersion.js +1 -1
  107. package/lib/packageVersion.js.map +1 -1
  108. package/lib/pendingStateManager.d.ts +18 -5
  109. package/lib/pendingStateManager.d.ts.map +1 -1
  110. package/lib/pendingStateManager.js +20 -13
  111. package/lib/pendingStateManager.js.map +1 -1
  112. package/lib/summary/documentSchema.d.ts +79 -16
  113. package/lib/summary/documentSchema.d.ts.map +1 -1
  114. package/lib/summary/documentSchema.js +119 -53
  115. package/lib/summary/documentSchema.js.map +1 -1
  116. package/lib/summary/index.d.ts +1 -1
  117. package/lib/summary/index.d.ts.map +1 -1
  118. package/lib/summary/index.js.map +1 -1
  119. package/package.json +18 -18
  120. package/src/channelCollection.ts +4 -4
  121. package/src/compatUtils.ts +147 -10
  122. package/src/containerRuntime.ts +242 -85
  123. package/src/dataStore.ts +7 -0
  124. package/src/gc/garbageCollection.ts +2 -0
  125. package/src/gc/gcDefinitions.ts +1 -1
  126. package/src/index.ts +4 -2
  127. package/src/messageTypes.ts +12 -5
  128. package/src/metadata.ts +1 -1
  129. package/src/opLifecycle/definitions.ts +7 -3
  130. package/src/opLifecycle/index.ts +1 -0
  131. package/src/opLifecycle/opGroupingManager.ts +17 -4
  132. package/src/opLifecycle/opSerialization.ts +6 -1
  133. package/src/packageVersion.ts +1 -1
  134. package/src/pendingStateManager.ts +49 -22
  135. package/src/summary/documentSchema.ts +228 -83
  136. package/src/summary/index.ts +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-runtime",
3
- "version": "2.41.0",
3
+ "version": "2.43.0-343119",
4
4
  "description": "Fluid container runtime",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -119,18 +119,18 @@
119
119
  "temp-directory": "nyc/.nyc_output"
120
120
  },
121
121
  "dependencies": {
122
- "@fluid-internal/client-utils": "~2.41.0",
123
- "@fluidframework/container-definitions": "~2.41.0",
124
- "@fluidframework/container-runtime-definitions": "~2.41.0",
125
- "@fluidframework/core-interfaces": "~2.41.0",
126
- "@fluidframework/core-utils": "~2.41.0",
127
- "@fluidframework/datastore": "~2.41.0",
128
- "@fluidframework/driver-definitions": "~2.41.0",
129
- "@fluidframework/driver-utils": "~2.41.0",
130
- "@fluidframework/id-compressor": "~2.41.0",
131
- "@fluidframework/runtime-definitions": "~2.41.0",
132
- "@fluidframework/runtime-utils": "~2.41.0",
133
- "@fluidframework/telemetry-utils": "~2.41.0",
122
+ "@fluid-internal/client-utils": "2.43.0-343119",
123
+ "@fluidframework/container-definitions": "2.43.0-343119",
124
+ "@fluidframework/container-runtime-definitions": "2.43.0-343119",
125
+ "@fluidframework/core-interfaces": "2.43.0-343119",
126
+ "@fluidframework/core-utils": "2.43.0-343119",
127
+ "@fluidframework/datastore": "2.43.0-343119",
128
+ "@fluidframework/driver-definitions": "2.43.0-343119",
129
+ "@fluidframework/driver-utils": "2.43.0-343119",
130
+ "@fluidframework/id-compressor": "2.43.0-343119",
131
+ "@fluidframework/runtime-definitions": "2.43.0-343119",
132
+ "@fluidframework/runtime-utils": "2.43.0-343119",
133
+ "@fluidframework/telemetry-utils": "2.43.0-343119",
134
134
  "@tylerbu/sorted-btree-es6": "^1.8.0",
135
135
  "double-ended-queue": "^2.1.0-0",
136
136
  "lz4js": "^0.2.0",
@@ -140,16 +140,16 @@
140
140
  "devDependencies": {
141
141
  "@arethetypeswrong/cli": "^0.17.1",
142
142
  "@biomejs/biome": "~1.9.3",
143
- "@fluid-internal/mocha-test-setup": "~2.41.0",
144
- "@fluid-private/stochastic-test-utils": "~2.41.0",
145
- "@fluid-private/test-pairwise-generator": "~2.41.0",
143
+ "@fluid-internal/mocha-test-setup": "2.43.0-343119",
144
+ "@fluid-private/stochastic-test-utils": "2.43.0-343119",
145
+ "@fluid-private/test-pairwise-generator": "2.43.0-343119",
146
146
  "@fluid-tools/benchmark": "^0.51.0",
147
147
  "@fluid-tools/build-cli": "^0.55.0",
148
148
  "@fluidframework/build-common": "^2.0.3",
149
149
  "@fluidframework/build-tools": "^0.55.0",
150
- "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.40.0",
150
+ "@fluidframework/container-runtime-previous": "npm:@fluidframework/container-runtime@2.42.0",
151
151
  "@fluidframework/eslint-config-fluid": "^5.7.4",
152
- "@fluidframework/test-runtime-utils": "~2.41.0",
152
+ "@fluidframework/test-runtime-utils": "2.43.0-343119",
153
153
  "@microsoft/api-extractor": "7.52.8",
154
154
  "@types/double-ended-queue": "^2.1.0",
155
155
  "@types/lz4js": "^0.2.0",
@@ -1116,10 +1116,10 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1116
1116
  context.processSignal(message, local);
1117
1117
  }
1118
1118
 
1119
- public setConnectionState(connected: boolean, clientId?: string): void {
1119
+ public setConnectionState(canSendOps: boolean, clientId?: string): void {
1120
1120
  for (const [fluidDataStoreId, context] of this.contexts) {
1121
1121
  try {
1122
- context.setConnectionState(connected, clientId);
1122
+ context.setConnectionState(canSendOps, clientId);
1123
1123
  } catch (error) {
1124
1124
  this.mc.logger.sendErrorEvent(
1125
1125
  {
@@ -1130,7 +1130,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1130
1130
  }),
1131
1131
  details: JSON.stringify({
1132
1132
  runtimeConnected: this.parentContext.connected,
1133
- connected,
1133
+ canSendOps,
1134
1134
  }),
1135
1135
  },
1136
1136
  error,
@@ -1544,7 +1544,7 @@ export class ChannelCollection implements IFluidDataStoreChannel, IDisposable {
1544
1544
  const id = requestParser.pathParts[0];
1545
1545
 
1546
1546
  // Differentiate between requesting the dataStore directly, or one of its children
1547
- const requestForChild = !requestParser.isLeaf(1);
1547
+ const requestForChild = requestParser.pathParts.length > 1;
1548
1548
 
1549
1549
  const headerData: RuntimeHeaderData = {};
1550
1550
  if (typeof request.headers?.[RuntimeHeaders.wait] === "boolean") {
@@ -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,
@@ -64,6 +66,8 @@ export type MinimumVersionForCollab =
64
66
  * String in a valid semver format of a specific version at least specifying minor.
65
67
  * Unlike {@link MinimumVersionForCollab}, this type allows any bigint for the major version.
66
68
  * Used as a more generic type that allows major versions other than 1 or 2.
69
+ *
70
+ * @internal
67
71
  */
68
72
  export type SemanticVersion =
69
73
  | `${bigint}.${bigint}.${bigint}`
@@ -78,6 +82,13 @@ export type ConfigMap<T extends Record<string, unknown>> = {
78
82
  };
79
83
  };
80
84
 
85
+ /**
86
+ * Generic type for runtimeOptionsAffectingDocSchemaConfigValidationMap
87
+ */
88
+ export type ConfigValidationMap<T extends Record<string, unknown>> = {
89
+ [K in keyof T]-?: (configValue: T[K]) => SemanticVersion | undefined;
90
+ };
91
+
81
92
  /**
82
93
  * Subset of the {@link ContainerRuntimeOptionsInternal} properties which
83
94
  * affect {@link IDocumentSchemaFeatures}.
@@ -119,11 +130,11 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
119
130
  enableGroupedBatching: {
120
131
  "1.0.0": false,
121
132
  "2.0.0-defaults": true,
122
- } as const,
133
+ },
123
134
  compressionOptions: {
124
135
  "1.0.0": disabledCompressionConfig,
125
136
  "2.0.0-defaults": enabledCompressionConfig,
126
- } as const,
137
+ },
127
138
  enableRuntimeIdCompressor: {
128
139
  // For IdCompressorMode, `undefined` represents a logical state (off).
129
140
  // However, to satisfy the Required<> constraint while
@@ -135,7 +146,7 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
135
146
  // Therefore, we will require customers to explicitly enable it. We
136
147
  // are keeping it as a DocSchema affecting option for now as this may
137
148
  // change in the future.
138
- } as const,
149
+ },
139
150
  explicitSchemaControl: {
140
151
  "1.0.0": false,
141
152
  // This option's intention is to prevent 1.x clients from joining sessions
@@ -149,34 +160,66 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
149
160
  // Only enable as a default when `minVersionForCollab` is specified at
150
161
  // 2.0.0+.
151
162
  "2.0.0": true,
152
- } as const,
163
+ },
153
164
  flushMode: {
154
165
  // Note: 1.x clients are compatible with TurnBased flushing, but here we elect to remain on Immediate flush mode
155
166
  // as a work-around for inability to send batches larger than 1Mb. Immediate flushing keeps batches smaller as
156
167
  // fewer messages will be included per flush.
157
168
  "1.0.0": FlushMode.Immediate,
158
169
  "2.0.0-defaults": FlushMode.TurnBased,
159
- } as const,
170
+ },
160
171
  gcOptions: {
161
172
  "1.0.0": {},
162
173
  // Although sweep is supported in 2.x, it is disabled by default until minVersionForCollab>=3.0.0 to be extra safe.
163
174
  "3.0.0": { enableGCSweep: true },
164
- } as const,
175
+ },
165
176
  createBlobPayloadPending: {
166
177
  // This feature is new and disabled by default. In the future we will enable it by default, but we have not
167
178
  // closed on the version where that will happen yet. Probably a .10 release since blob functionality is not
168
179
  // exposed on the `@public` API surface.
169
180
  "1.0.0": undefined,
170
- } as const,
181
+ },
171
182
  } as const satisfies ConfigMap<RuntimeOptionsAffectingDocSchema>;
172
183
 
184
+ const runtimeOptionsAffectingDocSchemaConfigValidationMap = {
185
+ enableGroupedBatching: configValueToMinVersionForCollab([
186
+ [false, "1.0.0"],
187
+ [true, "2.0.0-defaults"],
188
+ ]),
189
+ compressionOptions: configValueToMinVersionForCollab([
190
+ [{ ...disabledCompressionConfig }, "1.0.0"],
191
+ [{ ...enabledCompressionConfig }, "2.0.0-defaults"],
192
+ ]),
193
+ enableRuntimeIdCompressor: configValueToMinVersionForCollab([
194
+ [undefined, "1.0.0"],
195
+ ["on", "2.0.0-defaults"],
196
+ ["delayed", "2.0.0-defaults"],
197
+ ]),
198
+ explicitSchemaControl: configValueToMinVersionForCollab([
199
+ [false, "1.0.0"],
200
+ [true, "2.0.0-defaults"],
201
+ ]),
202
+ flushMode: configValueToMinVersionForCollab([
203
+ [FlushMode.Immediate, "1.0.0"],
204
+ [FlushMode.TurnBased, "2.0.0-defaults"],
205
+ ]),
206
+ gcOptions: configValueToMinVersionForCollab([
207
+ [{ enableGCSweep: undefined }, "1.0.0"],
208
+ [{ enableGCSweep: true }, "2.0.0-defaults"],
209
+ ]),
210
+ createBlobPayloadPending: configValueToMinVersionForCollab([
211
+ [undefined, "1.0.0"],
212
+ [true, "2.40.0"],
213
+ ]),
214
+ } as const satisfies ConfigValidationMap<RuntimeOptionsAffectingDocSchema>;
215
+
173
216
  /**
174
217
  * Returns the default RuntimeOptionsAffectingDocSchema configuration for a given minVersionForCollab.
175
218
  */
176
219
  export function getMinVersionForCollabDefaults(
177
220
  minVersionForCollab: MinimumVersionForCollab,
178
221
  ): RuntimeOptionsAffectingDocSchema {
179
- return getConfigsForCompatMode(
222
+ return getConfigsForMinVersionForCollab(
180
223
  minVersionForCollab,
181
224
  runtimeOptionsAffectingDocSchemaConfigMap,
182
225
  // This is a bad cast away from Partial that getConfigsForCompatMode provides.
@@ -187,7 +230,7 @@ export function getMinVersionForCollabDefaults(
187
230
  /**
188
231
  * Returns a default configuration given minVersionForCollab and configuration version map.
189
232
  */
190
- export function getConfigsForCompatMode<T extends Record<SemanticVersion, unknown>>(
233
+ export function getConfigsForMinVersionForCollab<T extends Record<SemanticVersion, unknown>>(
191
234
  minVersionForCollab: SemanticVersion,
192
235
  configMap: ConfigMap<T>,
193
236
  ): Partial<T> {
@@ -226,3 +269,97 @@ export function isValidMinVersionForCollab(
226
269
  lte(minVersionForCollab, pkgVersion)
227
270
  );
228
271
  }
272
+
273
+ /**
274
+ * Validates if the runtime options passed in from the user are compatible with the minVersionForCollab.
275
+ * For example, if a user sets the `enableGroupedBatching` option to true, but the minVersionForCollab
276
+ * is set to "1.0.0", then we should throw a UsageError since 1.x clients do not support batching.
277
+ * */
278
+ export function validateRuntimeOptions(
279
+ minVersionForCollab: MinimumVersionForCollab,
280
+ runtimeOptions: Partial<ContainerRuntimeOptionsInternal>,
281
+ ): void {
282
+ getValidationForRuntimeOptions<RuntimeOptionsAffectingDocSchema>(
283
+ minVersionForCollab,
284
+ runtimeOptions as Partial<RuntimeOptionsAffectingDocSchema>,
285
+ runtimeOptionsAffectingDocSchemaConfigValidationMap,
286
+ );
287
+ }
288
+
289
+ /**
290
+ * Generic function to validate runtime options against the minVersionForCollab.
291
+ */
292
+ export function getValidationForRuntimeOptions<T extends Record<string, unknown>>(
293
+ minVersionForCollab: SemanticVersion,
294
+ runtimeOptions: Partial<T>,
295
+ validationMap: ConfigValidationMap<T>,
296
+ ): void {
297
+ if (minVersionForCollab === defaultMinVersionForCollab) {
298
+ // If the minVersionForCollab is set to the default value, then we will not validate the runtime options
299
+ // This is to avoid disruption to users who have not yet set the minVersionForCollab value explicitly.
300
+ return;
301
+ }
302
+ // Iterate through each runtime option passed in by the user
303
+ for (const [passedRuntimeOption, passedRuntimeOptionValue] of Object.entries(
304
+ runtimeOptions,
305
+ ) as [keyof T & string, T[keyof T & string]][]) {
306
+ // Skip if passedRuntimeOption is not in validation map
307
+ if (!(passedRuntimeOption in validationMap)) {
308
+ continue;
309
+ }
310
+
311
+ const requiredVersion = validationMap[passedRuntimeOption](passedRuntimeOptionValue);
312
+ if (requiredVersion !== undefined && gt(requiredVersion, minVersionForCollab)) {
313
+ throw new UsageError(
314
+ `Runtime option ${passedRuntimeOption}:${JSON.stringify(passedRuntimeOptionValue)} requires ` +
315
+ `runtime version ${requiredVersion}. Please update minVersionForCollab ` +
316
+ `(currently ${minVersionForCollab}) to ${requiredVersion} or later to proceed.`,
317
+ );
318
+ }
319
+ }
320
+ }
321
+
322
+ /**
323
+ * Helper function to map ContainerRuntimeOptionsInternal config values to
324
+ * minVersionForCollab in {@link runtimeOptionsAffectingDocSchemaConfigValidationMap}.
325
+ */
326
+ export function configValueToMinVersionForCollab<
327
+ T extends string | number | boolean | undefined | object,
328
+ Arr extends readonly [T, SemanticVersion][],
329
+ >(configToMinVer: Arr): (configValue: T) => SemanticVersion | undefined {
330
+ const configValueToRequiredVersionMap = new Map(configToMinVer);
331
+ return (configValue: T) => {
332
+ // If the configValue is not an object then we can get the version required directly from the map.
333
+ if (typeof configValue !== "object") {
334
+ return configValueToRequiredVersionMap.get(configValue);
335
+ }
336
+ // When the input `configValue` is an object, this logic determines the minimum runtime version it requires.
337
+ // It iterates through each entry in `configValueToRequiredVersionMap`. If `possibleConfigValue` shares at
338
+ // least one key-value pair with the input `configValue`, its associated `versionRequired` is collected into
339
+ // `matchingVersions`. After checking all entries, the highest among the collected versions is returned.
340
+ // This represents the overall minimum version required to support the features implied by the input `configValue`.
341
+ const matchingVersions: SemanticVersion[] = [];
342
+ for (const [
343
+ possibleConfigValue,
344
+ versionRequired,
345
+ ] of configValueToRequiredVersionMap.entries()) {
346
+ assert(
347
+ typeof possibleConfigValue == "object",
348
+ 0xbb9 /* possibleConfigValue should be an object */,
349
+ );
350
+ // Check if `possibleConfigValue` and the input `configValue` share at least one
351
+ // common key-value pair. If they do, the `versionRequired` for this `possibleConfigValue`
352
+ // is added to `matchingVersions`.
353
+ if (Object.entries(possibleConfigValue).some(([k, v]) => configValue[k] === v)) {
354
+ matchingVersions.push(versionRequired);
355
+ }
356
+ }
357
+ if (matchingVersions.length > 0) {
358
+ // Return the latest minVersionForCollab among all matches.
359
+ return matchingVersions.sort((a, b) => compare(b, a))[0];
360
+ }
361
+ // If no matches then we return undefined. This means that the config value passed in
362
+ // does not require a specific minVersionForCollab to be valid.
363
+ return undefined;
364
+ };
365
+ }