@fluidframework/container-loader 2.33.2 → 2.40.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 (62) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/api-report/container-loader.legacy.alpha.api.md +0 -10
  3. package/dist/attachment.d.ts +2 -2
  4. package/dist/attachment.d.ts.map +1 -1
  5. package/dist/attachment.js.map +1 -1
  6. package/dist/container.d.ts +1 -14
  7. package/dist/container.d.ts.map +1 -1
  8. package/dist/container.js +4 -16
  9. package/dist/container.js.map +1 -1
  10. package/dist/containerStorageAdapter.d.ts +2 -2
  11. package/dist/containerStorageAdapter.d.ts.map +1 -1
  12. package/dist/containerStorageAdapter.js +2 -7
  13. package/dist/containerStorageAdapter.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/legacy.d.ts +0 -1
  18. package/dist/loader.d.ts +1 -29
  19. package/dist/loader.d.ts.map +1 -1
  20. package/dist/loader.js +1 -2
  21. package/dist/loader.js.map +1 -1
  22. package/dist/memoryBlobStorage.d.ts +30 -4
  23. package/dist/memoryBlobStorage.d.ts.map +1 -1
  24. package/dist/memoryBlobStorage.js +11 -28
  25. package/dist/memoryBlobStorage.js.map +1 -1
  26. package/dist/packageVersion.d.ts +1 -1
  27. package/dist/packageVersion.js +1 -1
  28. package/dist/packageVersion.js.map +1 -1
  29. package/lib/attachment.d.ts +2 -2
  30. package/lib/attachment.d.ts.map +1 -1
  31. package/lib/attachment.js.map +1 -1
  32. package/lib/container.d.ts +1 -14
  33. package/lib/container.d.ts.map +1 -1
  34. package/lib/container.js +5 -17
  35. package/lib/container.js.map +1 -1
  36. package/lib/containerStorageAdapter.d.ts +2 -2
  37. package/lib/containerStorageAdapter.d.ts.map +1 -1
  38. package/lib/containerStorageAdapter.js +2 -7
  39. package/lib/containerStorageAdapter.js.map +1 -1
  40. package/lib/index.d.ts +1 -1
  41. package/lib/index.d.ts.map +1 -1
  42. package/lib/index.js.map +1 -1
  43. package/lib/legacy.d.ts +0 -1
  44. package/lib/loader.d.ts +1 -29
  45. package/lib/loader.d.ts.map +1 -1
  46. package/lib/loader.js +1 -2
  47. package/lib/loader.js.map +1 -1
  48. package/lib/memoryBlobStorage.d.ts +30 -4
  49. package/lib/memoryBlobStorage.d.ts.map +1 -1
  50. package/lib/memoryBlobStorage.js +11 -27
  51. package/lib/memoryBlobStorage.js.map +1 -1
  52. package/lib/packageVersion.d.ts +1 -1
  53. package/lib/packageVersion.js +1 -1
  54. package/lib/packageVersion.js.map +1 -1
  55. package/package.json +17 -12
  56. package/src/attachment.ts +2 -4
  57. package/src/container.ts +8 -29
  58. package/src/containerStorageAdapter.ts +4 -8
  59. package/src/index.ts +0 -1
  60. package/src/loader.ts +0 -35
  61. package/src/memoryBlobStorage.ts +36 -45
  62. package/src/packageVersion.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/container-loader",
3
- "version": "2.33.2",
3
+ "version": "2.40.0",
4
4
  "description": "Fluid container loader",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -119,13 +119,13 @@
119
119
  "temp-directory": "nyc/.nyc_output"
120
120
  },
121
121
  "dependencies": {
122
- "@fluid-internal/client-utils": "~2.33.2",
123
- "@fluidframework/container-definitions": "~2.33.2",
124
- "@fluidframework/core-interfaces": "~2.33.2",
125
- "@fluidframework/core-utils": "~2.33.2",
126
- "@fluidframework/driver-definitions": "~2.33.2",
127
- "@fluidframework/driver-utils": "~2.33.2",
128
- "@fluidframework/telemetry-utils": "~2.33.2",
122
+ "@fluid-internal/client-utils": "~2.40.0",
123
+ "@fluidframework/container-definitions": "~2.40.0",
124
+ "@fluidframework/core-interfaces": "~2.40.0",
125
+ "@fluidframework/core-utils": "~2.40.0",
126
+ "@fluidframework/driver-definitions": "~2.40.0",
127
+ "@fluidframework/driver-utils": "~2.40.0",
128
+ "@fluidframework/telemetry-utils": "~2.40.0",
129
129
  "@types/events_pkg": "npm:@types/events@^3.0.0",
130
130
  "@ungap/structured-clone": "^1.2.0",
131
131
  "debug": "^4.3.4",
@@ -136,9 +136,9 @@
136
136
  "devDependencies": {
137
137
  "@arethetypeswrong/cli": "^0.17.1",
138
138
  "@biomejs/biome": "~1.9.3",
139
- "@fluid-internal/client-utils": "~2.33.2",
140
- "@fluid-internal/mocha-test-setup": "~2.33.2",
141
- "@fluid-private/test-loader-utils": "~2.33.2",
139
+ "@fluid-internal/client-utils": "~2.40.0",
140
+ "@fluid-internal/mocha-test-setup": "~2.40.0",
141
+ "@fluid-private/test-loader-utils": "~2.40.0",
142
142
  "@fluid-tools/build-cli": "^0.55.0",
143
143
  "@fluidframework/build-common": "^2.0.3",
144
144
  "@fluidframework/build-tools": "^0.55.0",
@@ -164,7 +164,12 @@
164
164
  "typescript": "~5.4.5"
165
165
  },
166
166
  "typeValidation": {
167
- "broken": {},
167
+ "broken": {
168
+ "TypeAlias_IDetachedBlobStorage": {
169
+ "forwardCompat": false,
170
+ "backCompat": false
171
+ }
172
+ },
168
173
  "entrypoint": "legacy"
169
174
  },
170
175
  "scripts": {
package/src/attachment.ts CHANGED
@@ -9,8 +9,7 @@ import { ISummaryTree } from "@fluidframework/driver-definitions";
9
9
  import { IDocumentStorageService } from "@fluidframework/driver-definitions/internal";
10
10
  import { CombinedAppAndProtocolSummary } from "@fluidframework/driver-utils/internal";
11
11
 
12
- // eslint-disable-next-line import/no-deprecated
13
- import { IDetachedBlobStorage } from "./loader.js";
12
+ import type { MemoryDetachedBlobStorage } from "./memoryBlobStorage.js";
14
13
  import type { SnapshotWithBlobs } from "./serializedStateManager.js";
15
14
  import { getSnapshotTreeAndBlobsFromSerializedContainer } from "./utils.js";
16
15
 
@@ -113,8 +112,7 @@ export interface AttachProcessProps {
113
112
  * The detached blob storage if it exists.
114
113
  */
115
114
  readonly detachedBlobStorage?: Pick<
116
- // eslint-disable-next-line import/no-deprecated
117
- IDetachedBlobStorage,
115
+ MemoryDetachedBlobStorage,
118
116
  "getBlobIds" | "readBlob" | "size"
119
117
  >;
120
118
 
package/src/container.ts CHANGED
@@ -72,7 +72,6 @@ import {
72
72
  ISequencedDocumentMessage,
73
73
  ISignalMessage,
74
74
  type ConnectionMode,
75
- type IContainerPackageInfo,
76
75
  } from "@fluidframework/driver-definitions/internal";
77
76
  import {
78
77
  getSnapshotTree,
@@ -128,14 +127,12 @@ import {
128
127
  getPackageName,
129
128
  } from "./contracts.js";
130
129
  import { DeltaManager, IConnectionArgs } from "./deltaManager.js";
131
- // eslint-disable-next-line import/no-deprecated
132
- import { IDetachedBlobStorage } from "./loader.js";
133
130
  import { RelativeLoader } from "./loader.js";
134
131
  import { validateRuntimeCompatibility } from "./loaderLayerCompatState.js";
135
132
  import {
136
- serializeMemoryDetachedBlobStorage,
137
133
  createMemoryDetachedBlobStorage,
138
134
  tryInitializeMemoryDetachedBlobStorage,
135
+ type MemoryDetachedBlobStorage,
139
136
  } from "./memoryBlobStorage.js";
140
137
  import { NoopHeuristic } from "./noopHeuristic.js";
141
138
  import { pkgVersion } from "./packageVersion.js";
@@ -241,12 +238,6 @@ export interface IContainerCreateProps {
241
238
  */
242
239
  readonly subLogger: ITelemetryLoggerExt;
243
240
 
244
- /**
245
- * Blobs storage for detached containers.
246
- */
247
- // eslint-disable-next-line import/no-deprecated
248
- readonly detachedBlobStorage?: IDetachedBlobStorage;
249
-
250
241
  /**
251
242
  * Optional property for allowing the container to use a custom
252
243
  * protocol implementation for handling the quorum and/or the audience.
@@ -492,8 +483,7 @@ export class Container
492
483
  private readonly options: ILoaderOptions;
493
484
  private readonly scope: FluidObject;
494
485
  private readonly subLogger: ITelemetryLoggerExt;
495
- // eslint-disable-next-line import/no-deprecated
496
- private readonly detachedBlobStorage: IDetachedBlobStorage | undefined;
486
+ private readonly detachedBlobStorage: MemoryDetachedBlobStorage | undefined;
497
487
  private readonly protocolHandlerBuilder: ProtocolHandlerBuilder;
498
488
  private readonly client: IClient;
499
489
 
@@ -724,17 +714,6 @@ export class Container
724
714
  return this._loadedCodeDetails;
725
715
  }
726
716
 
727
- /**
728
- * Get the package info for the code details that were used to load the container.
729
- * @returns The package info for the code details that were used to load the container if it is loaded, undefined otherwise
730
- * @deprecated To be removed in 2.40.
731
- * Use getLoadedCodeDetails instead; see https://github.com/microsoft/FluidFramework/issues/23898 for details.
732
- * Deprecating the function here to avoid polluting public container api surface.
733
- */
734
- public getContainerPackageInfo?(): IContainerPackageInfo | undefined {
735
- return getPackageName(this._loadedCodeDetails);
736
- }
737
-
738
717
  private _loadedModule: IFluidModuleWithDetails | undefined;
739
718
 
740
719
  /**
@@ -807,7 +786,6 @@ export class Container
807
786
  options,
808
787
  scope,
809
788
  subLogger,
810
- detachedBlobStorage,
811
789
  protocolHandlerBuilder,
812
790
  } = createProps;
813
791
 
@@ -1006,10 +984,7 @@ export class Container
1006
984
  this.detachedBlobStorage =
1007
985
  this.attachState === AttachState.Attached
1008
986
  ? undefined
1009
- : (detachedBlobStorage ??
1010
- (this.mc.config.getBoolean("Fluid.Container.MemoryBlobStorageEnabled") === false
1011
- ? undefined
1012
- : createMemoryDetachedBlobStorage()));
987
+ : createMemoryDetachedBlobStorage();
1013
988
 
1014
989
  this.storageAdapter = new ContainerStorageAdapter(
1015
990
  this.detachedBlobStorage,
@@ -1284,7 +1259,7 @@ export class Container
1284
1259
  pendingRuntimeState,
1285
1260
  hasAttachmentBlobs:
1286
1261
  this.detachedBlobStorage !== undefined && this.detachedBlobStorage.size > 0,
1287
- attachmentBlobs: serializeMemoryDetachedBlobStorage(this.detachedBlobStorage),
1262
+ attachmentBlobs: this.detachedBlobStorage?.serialize(),
1288
1263
  };
1289
1264
  return JSON.stringify(detachedContainerState);
1290
1265
  }
@@ -1846,6 +1821,10 @@ export class Container
1846
1821
  }: IPendingDetachedContainerState): Promise<void> {
1847
1822
  if (hasAttachmentBlobs) {
1848
1823
  if (attachmentBlobs !== undefined) {
1824
+ assert(
1825
+ this.detachedBlobStorage !== undefined,
1826
+ 0xb8e /* detached blob storage should always exist when detached */,
1827
+ );
1849
1828
  tryInitializeMemoryDetachedBlobStorage(this.detachedBlobStorage, attachmentBlobs);
1850
1829
  }
1851
1830
  assert(
@@ -23,8 +23,7 @@ import {
23
23
  import { isInstanceOfISnapshot, UsageError } from "@fluidframework/driver-utils/internal";
24
24
  import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
25
25
 
26
- // eslint-disable-next-line import/no-deprecated
27
- import { IDetachedBlobStorage } from "./loader.js";
26
+ import type { MemoryDetachedBlobStorage } from "./memoryBlobStorage.js";
28
27
  import { ProtocolTreeStorageService } from "./protocolTreeDocumentStorageService.js";
29
28
  import { RetriableDocumentStorageService } from "./retriableDocumentStorageService.js";
30
29
  import type {
@@ -80,8 +79,7 @@ export class ContainerStorageAdapter
80
79
  * @param enableSummarizeProtocolTree - Enable uploading a protocol summary. Note: preference is given to service policy's "summarizeProtocolTree" before this value.
81
80
  */
82
81
  public constructor(
83
- // eslint-disable-next-line import/no-deprecated
84
- detachedBlobStorage: IDetachedBlobStorage | undefined,
82
+ detachedBlobStorage: MemoryDetachedBlobStorage | undefined,
85
83
  private readonly logger: ITelemetryLoggerExt,
86
84
  /**
87
85
  * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
@@ -258,8 +256,7 @@ export class ContainerStorageAdapter
258
256
  */
259
257
  class BlobOnlyStorage implements IDocumentStorageService {
260
258
  constructor(
261
- // eslint-disable-next-line import/no-deprecated
262
- private readonly detachedStorage: IDetachedBlobStorage | undefined,
259
+ private readonly detachedStorage: MemoryDetachedBlobStorage | undefined,
263
260
  private readonly logger: ITelemetryLoggerExt,
264
261
  ) {}
265
262
 
@@ -271,8 +268,7 @@ class BlobOnlyStorage implements IDocumentStorageService {
271
268
  return this.verifyStorage().readBlob(blobId);
272
269
  }
273
270
 
274
- // eslint-disable-next-line import/no-deprecated
275
- private verifyStorage(): IDetachedBlobStorage {
271
+ private verifyStorage(): MemoryDetachedBlobStorage {
276
272
  if (this.detachedStorage === undefined) {
277
273
  throw new UsageError("Real storage calls not allowed in Unattached container");
278
274
  }
package/src/index.ts CHANGED
@@ -16,7 +16,6 @@ export {
16
16
  } from "./createAndLoadContainerUtils.js";
17
17
  export {
18
18
  ICodeDetailsLoader,
19
- IDetachedBlobStorage,
20
19
  IFluidModuleWithDetails,
21
20
  ILoaderProps,
22
21
  ILoaderServices,
package/src/loader.ts CHANGED
@@ -22,7 +22,6 @@ import {
22
22
  import { IClientDetails } from "@fluidframework/driver-definitions";
23
23
  import {
24
24
  IDocumentServiceFactory,
25
- IDocumentStorageService,
26
25
  IResolvedUrl,
27
26
  IUrlResolver,
28
27
  } from "@fluidframework/driver-definitions/internal";
@@ -170,11 +169,6 @@ export interface ILoaderProps {
170
169
  */
171
170
  readonly logger?: ITelemetryBaseLogger;
172
171
 
173
- /**
174
- * Blobs storage for detached containers.
175
- */
176
- readonly detachedBlobStorage?: IDetachedBlobStorage;
177
-
178
172
  /**
179
173
  * The configuration provider which may be used to control features.
180
174
  */
@@ -228,12 +222,6 @@ export interface ILoaderServices {
228
222
  */
229
223
  readonly subLogger: ITelemetryLoggerExt;
230
224
 
231
- /**
232
- * Blobs storage for detached containers.
233
- * @deprecated - IDetachedBlobStorage will be removed in a future release without a replacement. Blobs created while detached will be stored in memory to align with attached container behavior. AB#8049
234
- */
235
- readonly detachedBlobStorage?: IDetachedBlobStorage;
236
-
237
225
  /**
238
226
  * Optional property for allowing the container to use a custom
239
227
  * protocol implementation for handling the quorum and/or the audience.
@@ -241,27 +229,6 @@ export interface ILoaderServices {
241
229
  readonly protocolHandlerBuilder?: ProtocolHandlerBuilder;
242
230
  }
243
231
 
244
- /**
245
- * Subset of IDocumentStorageService which only supports createBlob() and readBlob(). This is used to support
246
- * blobs in detached containers.
247
- * @legacy
248
- * @alpha
249
- *
250
- * @deprecated - IDetachedBlobStorage will be removed in a future release without a replacement. Blobs created while detached will be stored in memory to align with attached container behavior. AB#8049
251
- */
252
- export type IDetachedBlobStorage = Pick<IDocumentStorageService, "createBlob" | "readBlob"> & {
253
- size: number;
254
- /**
255
- * Return an array of all blob IDs present in storage
256
- */
257
- getBlobIds(): string[];
258
-
259
- /**
260
- * After the container is attached, the detached blob storage is no longer needed and will be disposed.
261
- */
262
- dispose?(): void;
263
- };
264
-
265
232
  /**
266
233
  * Manages Fluid resource loading
267
234
  * @legacy
@@ -281,7 +248,6 @@ export class Loader implements IHostLoader {
281
248
  options,
282
249
  scope,
283
250
  logger,
284
- detachedBlobStorage,
285
251
  configProvider,
286
252
  protocolHandlerBuilder,
287
253
  } = loaderProps;
@@ -306,7 +272,6 @@ export class Loader implements IHostLoader {
306
272
  options: options ?? {},
307
273
  scope:
308
274
  options?.provideScopeLoader === false ? { ...scope } : { ...scope, ILoader: this },
309
- detachedBlobStorage,
310
275
  protocolHandlerBuilder,
311
276
  subLogger: subMc.logger,
312
277
  };
@@ -4,57 +4,40 @@
4
4
  */
5
5
 
6
6
  import { bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
7
- import { assert, isObject } from "@fluidframework/core-utils/internal";
8
- import type { ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
7
+ import { assert } from "@fluidframework/core-utils/internal";
8
+ import type {
9
+ ICreateBlobResponse,
10
+ IDocumentStorageService,
11
+ } from "@fluidframework/driver-definitions/internal";
9
12
 
10
- // eslint-disable-next-line import/no-deprecated
11
- import type { IDetachedBlobStorage } from "./loader.js";
12
-
13
- const MemoryDetachedBlobStorageIdentifier = Symbol();
13
+ /**
14
+ * An interface used to manage blobs in memory for detached containers.
15
+ *
16
+ * @remarks
17
+ * On attach of the container the blobs are read, and uploaded to the server.
18
+ * The interface also supports serialization and initialization which is
19
+ * used when serializing and rehydrating a detached container with blobs.
20
+ */
21
+ export interface MemoryDetachedBlobStorage
22
+ extends Pick<IDocumentStorageService, "createBlob" | "readBlob"> {
23
+ size: number;
24
+ /**
25
+ * Return an array of all blob IDs present in storage
26
+ */
27
+ getBlobIds(): string[];
14
28
 
15
- // eslint-disable-next-line import/no-deprecated
16
- interface MemoryDetachedBlobStorage extends IDetachedBlobStorage {
17
- [MemoryDetachedBlobStorageIdentifier]: typeof MemoryDetachedBlobStorageIdentifier;
29
+ /**
30
+ * After the container is attached, the detached blob storage is no longer needed and will be disposed.
31
+ */
32
+ dispose?(): void;
18
33
  initialize(attachmentBlobs: string[]): void;
19
34
  serialize(): string | undefined;
20
35
  }
21
36
 
22
- function isMemoryDetachedBlobStorage(
23
- // eslint-disable-next-line import/no-deprecated
24
- detachedStorage: IDetachedBlobStorage | undefined,
25
- ): detachedStorage is MemoryDetachedBlobStorage {
26
- return (
27
- isObject(detachedStorage) &&
28
- MemoryDetachedBlobStorageIdentifier in detachedStorage &&
29
- detachedStorage[MemoryDetachedBlobStorageIdentifier] ===
30
- MemoryDetachedBlobStorageIdentifier
31
- );
32
- }
33
-
34
- export function serializeMemoryDetachedBlobStorage(
35
- // eslint-disable-next-line import/no-deprecated
36
- detachedStorage: IDetachedBlobStorage | undefined,
37
- ): string | undefined {
38
- if (
39
- detachedStorage !== undefined &&
40
- detachedStorage.size > 0 &&
41
- isMemoryDetachedBlobStorage(detachedStorage)
42
- ) {
43
- return detachedStorage.serialize();
44
- }
45
- }
46
-
47
37
  export function tryInitializeMemoryDetachedBlobStorage(
48
- // eslint-disable-next-line import/no-deprecated
49
- detachedStorage: IDetachedBlobStorage | undefined,
38
+ detachedStorage: MemoryDetachedBlobStorage,
50
39
  attachmentBlobs: string,
51
40
  ): void {
52
- if (!isMemoryDetachedBlobStorage(detachedStorage)) {
53
- throw new Error(
54
- "DetachedBlobStorage was not provided to the loader during serialize so cannot be provided during rehydrate.",
55
- );
56
- }
57
-
58
41
  assert(detachedStorage.size === 0, 0x99e /* Blob storage already initialized */);
59
42
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
60
43
  const maybeAttachmentBlobs = JSON.parse(attachmentBlobs);
@@ -64,11 +47,16 @@ export function tryInitializeMemoryDetachedBlobStorage(
64
47
  detachedStorage.initialize(maybeAttachmentBlobs);
65
48
  }
66
49
 
50
+ /**
51
+ * Creates a new instance of `MemoryDetachedBlobStorage`.
52
+ * The returned storage allows for creating, reading, and managing blobs in memory.
53
+ * It also provides methods for serialization and initialization with attachment blobs.
54
+ * @returns A new `MemoryDetachedBlobStorage` instance.
55
+ */
67
56
  // eslint-disable-next-line import/no-deprecated
68
- export function createMemoryDetachedBlobStorage(): IDetachedBlobStorage {
57
+ export function createMemoryDetachedBlobStorage(): MemoryDetachedBlobStorage {
69
58
  const blobs: ArrayBufferLike[] = [];
70
59
  const storage: MemoryDetachedBlobStorage = {
71
- [MemoryDetachedBlobStorageIdentifier]: MemoryDetachedBlobStorageIdentifier,
72
60
  createBlob: async (file: ArrayBufferLike): Promise<ICreateBlobResponse> => ({
73
61
  id: `${blobs.push(file) - 1}`,
74
62
  }),
@@ -79,7 +67,10 @@ export function createMemoryDetachedBlobStorage(): IDetachedBlobStorage {
79
67
  },
80
68
  getBlobIds: (): string[] => blobs.map((_, i) => `${i}`),
81
69
  dispose: () => blobs.splice(0),
82
- serialize: () => JSON.stringify(blobs.map((b) => bufferToString(b, "utf8"))),
70
+ serialize: () =>
71
+ blobs.length > 0
72
+ ? JSON.stringify(blobs.map((b) => bufferToString(b, "utf8")))
73
+ : undefined,
83
74
  initialize: (attachmentBlobs: string[]) =>
84
75
  blobs.push(...attachmentBlobs.map((maybeBlob) => stringToBuffer(maybeBlob, "utf8"))),
85
76
  };
@@ -6,4 +6,4 @@
6
6
  */
7
7
 
8
8
  export const pkgName = "@fluidframework/container-loader";
9
- export const pkgVersion = "2.33.2";
9
+ export const pkgVersion = "2.40.0";