@fluidframework/container-runtime 2.61.0-355054 → 2.61.0-355603

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 (57) hide show
  1. package/api-report/container-runtime.legacy.beta.api.md +2 -1
  2. package/container-runtime.test-files.tar +0 -0
  3. package/dist/blobManager/blobManager.d.ts +13 -2
  4. package/dist/blobManager/blobManager.d.ts.map +1 -1
  5. package/dist/blobManager/blobManager.js +41 -24
  6. package/dist/blobManager/blobManager.js.map +1 -1
  7. package/dist/channelCollection.d.ts +6 -2
  8. package/dist/channelCollection.d.ts.map +1 -1
  9. package/dist/channelCollection.js +1 -0
  10. package/dist/channelCollection.js.map +1 -1
  11. package/dist/containerCompatibility.d.ts +18 -0
  12. package/dist/containerCompatibility.d.ts.map +1 -1
  13. package/dist/containerCompatibility.js +23 -1
  14. package/dist/containerCompatibility.js.map +1 -1
  15. package/dist/containerRuntime.d.ts +15 -3
  16. package/dist/containerRuntime.d.ts.map +1 -1
  17. package/dist/containerRuntime.js +74 -51
  18. package/dist/containerRuntime.js.map +1 -1
  19. package/dist/dataStoreContext.d.ts +5 -1
  20. package/dist/dataStoreContext.d.ts.map +1 -1
  21. package/dist/dataStoreContext.js +1 -0
  22. package/dist/dataStoreContext.js.map +1 -1
  23. package/dist/packageVersion.d.ts +1 -1
  24. package/dist/packageVersion.js +1 -1
  25. package/dist/packageVersion.js.map +1 -1
  26. package/internal.d.ts +1 -1
  27. package/legacy.d.ts +1 -1
  28. package/lib/blobManager/blobManager.d.ts +13 -2
  29. package/lib/blobManager/blobManager.d.ts.map +1 -1
  30. package/lib/blobManager/blobManager.js +41 -24
  31. package/lib/blobManager/blobManager.js.map +1 -1
  32. package/lib/channelCollection.d.ts +6 -2
  33. package/lib/channelCollection.d.ts.map +1 -1
  34. package/lib/channelCollection.js +1 -0
  35. package/lib/channelCollection.js.map +1 -1
  36. package/lib/containerCompatibility.d.ts +18 -0
  37. package/lib/containerCompatibility.d.ts.map +1 -1
  38. package/lib/containerCompatibility.js +22 -0
  39. package/lib/containerCompatibility.js.map +1 -1
  40. package/lib/containerRuntime.d.ts +15 -3
  41. package/lib/containerRuntime.d.ts.map +1 -1
  42. package/lib/containerRuntime.js +25 -2
  43. package/lib/containerRuntime.js.map +1 -1
  44. package/lib/dataStoreContext.d.ts +5 -1
  45. package/lib/dataStoreContext.d.ts.map +1 -1
  46. package/lib/dataStoreContext.js +1 -0
  47. package/lib/dataStoreContext.js.map +1 -1
  48. package/lib/packageVersion.d.ts +1 -1
  49. package/lib/packageVersion.js +1 -1
  50. package/lib/packageVersion.js.map +1 -1
  51. package/package.json +20 -20
  52. package/src/blobManager/blobManager.ts +21 -3
  53. package/src/channelCollection.ts +9 -1
  54. package/src/containerCompatibility.ts +56 -0
  55. package/src/containerRuntime.ts +34 -3
  56. package/src/dataStoreContext.ts +7 -0
  57. package/src/packageVersion.ts +1 -1
@@ -129,7 +129,7 @@ export class BlobHandle
129
129
  // the contract explicit and reduces the amount of mocking required for tests.
130
130
  export type IBlobManagerRuntime = Pick<
131
131
  IContainerRuntime,
132
- "attachState" | "connected" | "baseLogger" | "clientDetails" | "disposed"
132
+ "attachState" | "baseLogger" | "disposed"
133
133
  > &
134
134
  IEventProvider<IContainerRuntimeEvents>;
135
135
 
@@ -328,6 +328,24 @@ export class BlobManager {
328
328
  return this.redirectTable.get(localId) !== undefined;
329
329
  }
330
330
 
331
+ /**
332
+ * Lookup the blob storage ID for a given local blob id.
333
+ * @param localId - The local blob id. Likely coming from a handle.
334
+ * @returns The storage ID if found and the blob is not pending, undefined otherwise.
335
+ * @remarks
336
+ * For blobs with pending payloads (localId exists but upload hasn't finished), this is expected to return undefined.
337
+ * Consumers should use the observability APIs on the handle (handle.payloadState, payloadShared event)
338
+ * to understand/wait for storage ID availability.
339
+ * Similarly, when the runtime is detached, this will return undefined as no blobs have been uploaded to storage.
340
+ */
341
+ public lookupTemporaryBlobStorageId(localId: string): string | undefined {
342
+ if (this.runtime.attachState === AttachState.Detached) {
343
+ return undefined;
344
+ }
345
+ // Get the storage ID from the redirect table
346
+ return this.redirectTable.get(localId);
347
+ }
348
+
331
349
  /**
332
350
  * Retrieve the blob with the given local blob id.
333
351
  * @param localId - The local blob id. Likely coming from a handle.
@@ -835,7 +853,7 @@ export class BlobManager {
835
853
  * The provided table must have exactly the same set of pseudo storage IDs as are found in the redirect table.
836
854
  * @param detachedStorageTable - A map of pseudo storage IDs to real storage IDs.
837
855
  */
838
- public patchRedirectTable(detachedStorageTable: Map<string, string>): void {
856
+ public readonly patchRedirectTable = (detachedStorageTable: Map<string, string>): void => {
839
857
  assert(
840
858
  this.runtime.attachState === AttachState.Detached,
841
859
  0x252 /* "redirect table can only be set in detached container" */,
@@ -858,7 +876,7 @@ export class BlobManager {
858
876
  // set identity (id -> id) entry
859
877
  this.setRedirection(newStorageId, newStorageId);
860
878
  }
861
- }
879
+ };
862
880
 
863
881
  /**
864
882
  * To be used in getPendingLocalState flow. Get a serializable record of the blobs that are
@@ -46,6 +46,7 @@ import {
46
46
  type IRuntimeMessagesContent,
47
47
  type InboundAttachMessage,
48
48
  type IRuntimeMessageCollection,
49
+ type MinimumVersionForCollab,
49
50
  } from "@fluidframework/runtime-definitions/internal";
50
51
  import {
51
52
  GCDataBuilder,
@@ -127,8 +128,14 @@ interface FluidDataStoreMessage {
127
128
  * being staged on IFluidParentContext can be added here as well, likely with optionality removed,
128
129
  * to ease interactions within this package.
129
130
  */
130
- export interface IFluidParentContextPrivate extends Omit<IFluidParentContext, "isReadOnly"> {
131
+ export interface IFluidParentContextPrivate
132
+ extends Omit<IFluidParentContext, "isReadOnly" | "minVersionForCollab"> {
131
133
  readonly isReadOnly: () => boolean;
134
+
135
+ /**
136
+ * {@inheritdoc IFluidParentContext.minVersionForCollab}
137
+ */
138
+ readonly minVersionForCollab: MinimumVersionForCollab;
132
139
  }
133
140
 
134
141
  /**
@@ -198,6 +205,7 @@ export function wrapContext(context: IFluidParentContextPrivate): IFluidParentCo
198
205
  setChannelDirty: (address: string) => {
199
206
  return context.setChannelDirty(address);
200
207
  },
208
+ minVersionForCollab: context.minVersionForCollab,
201
209
  };
202
210
  }
203
211
 
@@ -45,6 +45,49 @@ export type RuntimeOptionsAffectingDocSchema = Omit<
45
45
  | "summaryOptions"
46
46
  >;
47
47
 
48
+ /**
49
+ * Subset of {@link RuntimeOptionsAffectingDocSchema} which existed prior to the introduction of explicitSchemaControl.
50
+ *
51
+ * @remarks
52
+ * Runtime options that affect document schema should generally require explicitSchemaControl to be enabled.
53
+ * However, to prevent disruption to existing customers, options that existed prior to explicitSchemaControl
54
+ * do not explicity require explicitSchemaControl to be enabled. Do not add new options to this list.
55
+ */
56
+ type RuntimeOptionKeysPredatingExplicitSchemaControl = keyof Pick<
57
+ RuntimeOptionsAffectingDocSchema,
58
+ | "explicitSchemaControl"
59
+ | "compressionOptions"
60
+ | "enableRuntimeIdCompressor"
61
+ | "flushMode"
62
+ | "gcOptions"
63
+ | "enableGroupedBatching"
64
+ >;
65
+
66
+ /**
67
+ * List of keys of {@link RuntimeOptionsAffectingDocSchema} which existed prior to the introduction of explicitSchemaControl.
68
+ *
69
+ * @remarks
70
+ * Runtime options that affect document schema should generally require explicitSchemaControl to be enabled.
71
+ * However, to prevent disruption to existing customers, options that existed prior to explicitSchemaControl
72
+ * do not explicity require explicitSchemaControl to be enabled. Do not add new keys to this list.
73
+ */
74
+ const keysOfOptionsPredatingExplicitSchemaControl = new Set([
75
+ "explicitSchemaControl",
76
+ "compressionOptions",
77
+ "enableRuntimeIdCompressor",
78
+ "flushMode",
79
+ "gcOptions",
80
+ "enableGroupedBatching",
81
+ ]) satisfies Set<RuntimeOptionKeysPredatingExplicitSchemaControl>;
82
+
83
+ /**
84
+ * Subset of {@link RuntimeOptionsAffectingDocSchema} which require explicitSchemaControl to be enabled.
85
+ */
86
+ export type RuntimeOptionKeysThatRequireExplicitSchemaControl = keyof Omit<
87
+ RuntimeOptionsAffectingDocSchema,
88
+ RuntimeOptionKeysPredatingExplicitSchemaControl
89
+ >;
90
+
48
91
  /**
49
92
  * Mapping of RuntimeOptionsAffectingDocSchema to their compatibility related configs.
50
93
  *
@@ -113,6 +156,19 @@ const runtimeOptionsAffectingDocSchemaConfigMap = {
113
156
  },
114
157
  } as const satisfies ConfigMap<RuntimeOptionsAffectingDocSchema>;
115
158
 
159
+ /**
160
+ * Keys of {@link ContainerRuntimeOptionsInternal} that require explicitSchemaControl to be enabled.
161
+ */
162
+ export const runtimeOptionKeysThatRequireExplicitSchemaControl = (
163
+ Object.keys(
164
+ runtimeOptionsAffectingDocSchemaConfigMap,
165
+ ) as (keyof RuntimeOptionsAffectingDocSchema)[]
166
+ ).filter((key) => {
167
+ return !keysOfOptionsPredatingExplicitSchemaControl.has(
168
+ key as RuntimeOptionKeysPredatingExplicitSchemaControl,
169
+ );
170
+ }) as RuntimeOptionKeysThatRequireExplicitSchemaControl[];
171
+
116
172
  const runtimeOptionsAffectingDocSchemaConfigValidationMap = {
117
173
  enableGroupedBatching: configValueToMinVersionForCollab([
118
174
  [false, "1.0.0"],
@@ -130,7 +130,6 @@ import type {
130
130
  import {
131
131
  defaultMinVersionForCollab,
132
132
  isValidMinVersionForCollab,
133
- type SemanticVersion,
134
133
  } from "@fluidframework/runtime-utils/internal";
135
134
  import {
136
135
  GCDataBuilder,
@@ -144,6 +143,7 @@ import {
144
143
  exceptionToResponse,
145
144
  seqFromTree,
146
145
  } from "@fluidframework/runtime-utils/internal";
146
+ import { semanticVersionToMinimumVersionForCollab } from "@fluidframework/runtime-utils/internal";
147
147
  import type {
148
148
  IEventSampler,
149
149
  IFluidErrorBase,
@@ -195,6 +195,8 @@ import {
195
195
  getMinVersionForCollabDefaults,
196
196
  type RuntimeOptionsAffectingDocSchema,
197
197
  validateRuntimeOptions,
198
+ runtimeOptionKeysThatRequireExplicitSchemaControl,
199
+ type RuntimeOptionKeysThatRequireExplicitSchemaControl,
198
200
  } from "./containerCompatibility.js";
199
201
  import { ContainerFluidHandleContext } from "./containerHandleContext.js";
200
202
  import { channelToDataStore } from "./dataStore.js";
@@ -947,6 +949,19 @@ export class ContainerRuntime
947
949
  createBlobPayloadPending = defaultConfigs.createBlobPayloadPending,
948
950
  }: IContainerRuntimeOptionsInternal = runtimeOptions;
949
951
 
952
+ // If explicitSchemaControl is off, ensure that options which require explicitSchemaControl are not enabled.
953
+ if (!explicitSchemaControl) {
954
+ const disallowedKeys = Object.keys(runtimeOptions).filter(
955
+ (key) =>
956
+ runtimeOptionKeysThatRequireExplicitSchemaControl.includes(
957
+ key as RuntimeOptionKeysThatRequireExplicitSchemaControl,
958
+ ) && runtimeOptions[key] !== undefined,
959
+ );
960
+ if (disallowedKeys.length > 0) {
961
+ throw new UsageError(`explicitSchemaControl must be enabled to use ${disallowedKeys}`);
962
+ }
963
+ }
964
+
950
965
  // The logic for enableRuntimeIdCompressor is a bit different. Since `undefined` represents a logical state (off)
951
966
  // we need to check it's explicitly set in runtimeOptions. If so, we should use that value even if it's undefined.
952
967
  const enableRuntimeIdCompressor =
@@ -1181,7 +1196,7 @@ export class ContainerRuntime
1181
1196
  documentSchemaController,
1182
1197
  featureGatesForTelemetry,
1183
1198
  provideEntryPoint,
1184
- updatedMinVersionForCollab,
1199
+ semanticVersionToMinimumVersionForCollab(updatedMinVersionForCollab),
1185
1200
  requestHandler,
1186
1201
  undefined, // summaryConfiguration
1187
1202
  recentBatchInfo,
@@ -1503,7 +1518,7 @@ export class ContainerRuntime
1503
1518
  private readonly documentsSchemaController: DocumentsSchemaController,
1504
1519
  featureGatesForTelemetry: Record<string, boolean | number | undefined>,
1505
1520
  provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>,
1506
- private readonly minVersionForCollab: SemanticVersion,
1521
+ public readonly minVersionForCollab: MinimumVersionForCollab,
1507
1522
  private readonly requestHandler?: (
1508
1523
  request: IRequest,
1509
1524
  runtime: IContainerRuntime,
@@ -4520,6 +4535,22 @@ export class ContainerRuntime
4520
4535
  return this.blobManager.createBlob(blob, signal);
4521
4536
  }
4522
4537
 
4538
+ /**
4539
+ * Lookup the blob storage ID for a given local blob id.
4540
+ * @param localId - The local blob id. Likely coming from a handle.
4541
+ * @returns The storage ID if found and the blob is not pending, undefined otherwise.
4542
+ * @remarks
4543
+ * This method provides access to the BlobManager's storage ID lookup functionality.
4544
+ * For blobs with pending payloads (localId exists but upload hasn't finished), this returns undefined.
4545
+ * Consumers should use the observability APIs on the handle to understand/wait for storage ID availability.
4546
+ *
4547
+ * Warning: the returned blob URL may expire and does not support permalinks.
4548
+ * This API is intended for temporary integration scenarios only.
4549
+ */
4550
+ public lookupTemporaryBlobStorageId(localId: string): string | undefined {
4551
+ return this.blobManager.lookupTemporaryBlobStorageId(localId);
4552
+ }
4553
+
4523
4554
  private submitIdAllocationOpIfNeeded({
4524
4555
  resubmitOutstandingRanges = false,
4525
4556
  staged,
@@ -67,6 +67,7 @@ import {
67
67
  type IFluidDataStoreFactory,
68
68
  type PackagePath,
69
69
  type IRuntimeStorageService,
70
+ type MinimumVersionForCollab,
70
71
  } from "@fluidframework/runtime-definitions/internal";
71
72
  import {
72
73
  addBlobToSummary,
@@ -351,6 +352,11 @@ export abstract class FluidDataStoreContext
351
352
  return runtimeCompatDetailsForDataStore;
352
353
  }
353
354
 
355
+ /**
356
+ * {@inheritdoc IFluidDataStoreContext.minVersionForCollab}
357
+ */
358
+ public readonly minVersionForCollab: MinimumVersionForCollab;
359
+
354
360
  private baseSnapshotSequenceNumber: number | undefined;
355
361
 
356
362
  /**
@@ -460,6 +466,7 @@ export abstract class FluidDataStoreContext
460
466
 
461
467
  this._containerRuntime = props.parentContext.containerRuntime;
462
468
  this.parentContext = props.parentContext;
469
+ this.minVersionForCollab = props.parentContext.minVersionForCollab;
463
470
  this.id = props.id;
464
471
  this.storage = props.storage;
465
472
  this.scope = props.scope;
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-runtime";
9
- export const pkgVersion = "2.61.0-355054";
9
+ export const pkgVersion = "2.61.0-355603";