@fluidframework/container-runtime 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 (92) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/api-report/container-runtime.legacy.alpha.api.md +4 -0
  3. package/container-runtime.test-files.tar +0 -0
  4. package/dist/blobManager/blobManager.d.ts +31 -8
  5. package/dist/blobManager/blobManager.d.ts.map +1 -1
  6. package/dist/blobManager/blobManager.js +90 -17
  7. package/dist/blobManager/blobManager.js.map +1 -1
  8. package/dist/channelCollection.d.ts +26 -10
  9. package/dist/channelCollection.d.ts.map +1 -1
  10. package/dist/channelCollection.js +42 -11
  11. package/dist/channelCollection.js.map +1 -1
  12. package/dist/compatUtils.d.ts +19 -10
  13. package/dist/compatUtils.d.ts.map +1 -1
  14. package/dist/compatUtils.js +39 -32
  15. package/dist/compatUtils.js.map +1 -1
  16. package/dist/containerRuntime.d.ts +29 -13
  17. package/dist/containerRuntime.d.ts.map +1 -1
  18. package/dist/containerRuntime.js +139 -149
  19. package/dist/containerRuntime.js.map +1 -1
  20. package/dist/dataStoreContext.d.ts +15 -16
  21. package/dist/dataStoreContext.d.ts.map +1 -1
  22. package/dist/dataStoreContext.js +37 -19
  23. package/dist/dataStoreContext.js.map +1 -1
  24. package/dist/index.d.ts +1 -3
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -9
  27. package/dist/index.js.map +1 -1
  28. package/dist/legacy.d.ts +1 -0
  29. package/dist/opLifecycle/index.d.ts +1 -1
  30. package/dist/opLifecycle/index.d.ts.map +1 -1
  31. package/dist/opLifecycle/index.js.map +1 -1
  32. package/dist/opLifecycle/outbox.d.ts +20 -7
  33. package/dist/opLifecycle/outbox.d.ts.map +1 -1
  34. package/dist/opLifecycle/outbox.js +16 -20
  35. package/dist/opLifecycle/outbox.js.map +1 -1
  36. package/dist/packageVersion.d.ts +1 -1
  37. package/dist/packageVersion.js +1 -1
  38. package/dist/packageVersion.js.map +1 -1
  39. package/dist/pendingStateManager.d.ts +22 -8
  40. package/dist/pendingStateManager.d.ts.map +1 -1
  41. package/dist/pendingStateManager.js +11 -16
  42. package/dist/pendingStateManager.js.map +1 -1
  43. package/lib/blobManager/blobManager.d.ts +31 -8
  44. package/lib/blobManager/blobManager.d.ts.map +1 -1
  45. package/lib/blobManager/blobManager.js +91 -18
  46. package/lib/blobManager/blobManager.js.map +1 -1
  47. package/lib/channelCollection.d.ts +26 -10
  48. package/lib/channelCollection.d.ts.map +1 -1
  49. package/lib/channelCollection.js +43 -12
  50. package/lib/channelCollection.js.map +1 -1
  51. package/lib/compatUtils.d.ts +19 -10
  52. package/lib/compatUtils.d.ts.map +1 -1
  53. package/lib/compatUtils.js +36 -29
  54. package/lib/compatUtils.js.map +1 -1
  55. package/lib/containerRuntime.d.ts +29 -13
  56. package/lib/containerRuntime.d.ts.map +1 -1
  57. package/lib/containerRuntime.js +60 -70
  58. package/lib/containerRuntime.js.map +1 -1
  59. package/lib/dataStoreContext.d.ts +15 -16
  60. package/lib/dataStoreContext.d.ts.map +1 -1
  61. package/lib/dataStoreContext.js +38 -20
  62. package/lib/dataStoreContext.js.map +1 -1
  63. package/lib/index.d.ts +1 -3
  64. package/lib/index.d.ts.map +1 -1
  65. package/lib/index.js +0 -3
  66. package/lib/index.js.map +1 -1
  67. package/lib/legacy.d.ts +1 -0
  68. package/lib/opLifecycle/index.d.ts +1 -1
  69. package/lib/opLifecycle/index.d.ts.map +1 -1
  70. package/lib/opLifecycle/index.js.map +1 -1
  71. package/lib/opLifecycle/outbox.d.ts +20 -7
  72. package/lib/opLifecycle/outbox.d.ts.map +1 -1
  73. package/lib/opLifecycle/outbox.js +16 -20
  74. package/lib/opLifecycle/outbox.js.map +1 -1
  75. package/lib/packageVersion.d.ts +1 -1
  76. package/lib/packageVersion.js +1 -1
  77. package/lib/packageVersion.js.map +1 -1
  78. package/lib/pendingStateManager.d.ts +22 -8
  79. package/lib/pendingStateManager.d.ts.map +1 -1
  80. package/lib/pendingStateManager.js +11 -16
  81. package/lib/pendingStateManager.js.map +1 -1
  82. package/package.json +18 -18
  83. package/src/blobManager/blobManager.ts +141 -33
  84. package/src/channelCollection.ts +77 -19
  85. package/src/compatUtils.ts +53 -30
  86. package/src/containerRuntime.ts +102 -81
  87. package/src/dataStoreContext.ts +48 -38
  88. package/src/index.ts +1 -13
  89. package/src/opLifecycle/index.ts +1 -0
  90. package/src/opLifecycle/outbox.ts +42 -33
  91. package/src/packageVersion.ts +1 -1
  92. package/src/pendingStateManager.ts +37 -20
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @fluidframework/container-runtime
2
2
 
3
+ ## 2.40.0
4
+
5
+ ### Minor Changes
6
+
7
+ - IFluidHandleInternal.bind has been deprecated ([#24553](https://github.com/microsoft/FluidFramework/pull/24553)) [8a4362a7ed](https://github.com/microsoft/FluidFramework/commit/8a4362a7edef3a97fee13c9d23bea49448ba2a6a)
8
+
9
+ Handle binding is an internal concept used to make sure objects attach to the Container graph when their handle is stored in a DDS which is itself attached.
10
+ The source of the "bind" operation has been assumed to be any handle, but only one implementation is actually supported (`SharedObjectHandle`, not exported itself).
11
+
12
+ So the `bind` function is now deprecated on the `IFluidHandleInterface`, moving instead to internal types supporting the one valid implementation.
13
+ It's also deprecated on the various exported handle implementations that don't support it (each is either no-op, pass-through, or throwing).
14
+
15
+ No replacement is offered, this API was never meant to be called from outside of the Fluid Framework.
16
+
3
17
  ## 2.33.0
4
18
 
5
19
  Dependency updates only.
@@ -338,6 +338,7 @@ export interface LoadContainerRuntimeParams {
338
338
  containerScope?: FluidObject;
339
339
  context: IContainerContext;
340
340
  existing: boolean;
341
+ minVersionForCollab?: MinimumVersionForCollab;
341
342
  provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>;
342
343
  registryEntries: NamedFluidDataStoreRegistryEntries;
343
344
  // @deprecated
@@ -345,6 +346,9 @@ export interface LoadContainerRuntimeParams {
345
346
  runtimeOptions?: IContainerRuntimeOptions;
346
347
  }
347
348
 
349
+ // @alpha @legacy
350
+ export type MinimumVersionForCollab = `${1 | 2}.${bigint}.${bigint}` | `${1 | 2}.${bigint}.${bigint}-${string}`;
351
+
348
352
  // @alpha @deprecated @legacy (undocumented)
349
353
  export type OmitAttributesVersions<T> = Omit<T, "snapshotFormatVersion" | "summaryFormatVersion">;
350
354
 
Binary file
@@ -2,9 +2,8 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { TypedEventEmitter } from "@fluid-internal/client-utils";
6
5
  import { IContainerRuntime, IContainerRuntimeEvents } from "@fluidframework/container-runtime-definitions/internal";
7
- import type { IEvent, IEventProvider, IFluidHandleContext, IFluidHandleInternal, IFluidHandleInternalPayloadPending } from "@fluidframework/core-interfaces/internal";
6
+ import type { IEventProvider, IFluidHandleContext, IFluidHandleInternal, IFluidHandleInternalPayloadPending, ILocalFluidHandle, ILocalFluidHandleEvents, Listenable, PayloadState } from "@fluidframework/core-interfaces/internal";
8
7
  import { IDocumentStorageService, ICreateBlobResponse } from "@fluidframework/driver-definitions/internal";
9
8
  import { IGarbageCollectionData, ISummaryTreeWithStats, ITelemetryContext, type ISequencedMessageEnvelope } from "@fluidframework/runtime-definitions/internal";
10
9
  import { FluidHandleBase } from "@fluidframework/runtime-utils/internal";
@@ -16,7 +15,7 @@ import { type IBlobManagerLoadInfo } from "./blobManagerSnapSum.js";
16
15
  * DataObject.request() recognizes requests in the form of `/blobs/<id>`
17
16
  * and loads blob.
18
17
  */
19
- export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> implements IFluidHandleInternalPayloadPending<ArrayBufferLike> {
18
+ export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> implements ILocalFluidHandle<ArrayBufferLike>, IFluidHandleInternalPayloadPending<ArrayBufferLike> {
20
19
  readonly path: string;
21
20
  readonly routeContext: IFluidHandleContext;
22
21
  get: () => Promise<ArrayBufferLike>;
@@ -24,12 +23,27 @@ export declare class BlobHandle extends FluidHandleBase<ArrayBufferLike> impleme
24
23
  private readonly onAttachGraph?;
25
24
  private attached;
26
25
  get isAttached(): boolean;
26
+ private _events;
27
+ get events(): Listenable<ILocalFluidHandleEvents>;
28
+ private _state;
29
+ get payloadState(): PayloadState;
30
+ /**
31
+ * The error property starts undefined, signalling that there has been no error yet.
32
+ * If an error occurs, the property will contain the error.
33
+ */
34
+ private _payloadShareError;
35
+ get payloadShareError(): unknown;
27
36
  readonly absolutePath: string;
28
37
  constructor(path: string, routeContext: IFluidHandleContext, get: () => Promise<ArrayBufferLike>, payloadPending: boolean, onAttachGraph?: (() => void) | undefined);
38
+ readonly notifyShared: () => void;
39
+ readonly notifyFailed: (error: unknown) => void;
29
40
  attachGraph(): void;
41
+ /**
42
+ * @deprecated No replacement provided. Arbitrary handles may not serve as a bind source.
43
+ */
30
44
  bind(handle: IFluidHandleInternal): void;
31
45
  }
32
- export type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState" | "connected" | "baseLogger" | "clientDetails" | "disposed"> & TypedEventEmitter<IContainerRuntimeEvents>;
46
+ export type IBlobManagerRuntime = Pick<IContainerRuntime, "attachState" | "connected" | "baseLogger" | "clientDetails" | "disposed"> & IEventProvider<IContainerRuntimeEvents>;
33
47
  export interface IPendingBlobs {
34
48
  [localId: string]: {
35
49
  blob: string;
@@ -39,14 +53,14 @@ export interface IPendingBlobs {
39
53
  acked?: boolean;
40
54
  };
41
55
  }
42
- export interface IBlobManagerEvents extends IEvent {
43
- (event: "noPendingBlobs", listener: () => void): any;
56
+ export interface IBlobManagerEvents {
57
+ noPendingBlobs: () => void;
44
58
  }
45
59
  export declare const blobManagerBasePath: "_blobs";
46
60
  export declare class BlobManager {
47
61
  private readonly mc;
48
62
  private readonly publicEvents;
49
- get events(): IEventProvider<IBlobManagerEvents>;
63
+ get events(): Listenable<IBlobManagerEvents>;
50
64
  private readonly internalEvents;
51
65
  /**
52
66
  * Map of local IDs to storage IDs. Contains identity entries (storageId → storageId) for storage IDs. All requested IDs should
@@ -76,6 +90,7 @@ export declare class BlobManager {
76
90
  private readonly localBlobIdGenerator;
77
91
  private readonly pendingStashedBlobs;
78
92
  readonly stashedBlobsUploadP: Promise<(void | ICreateBlobResponse)[]>;
93
+ private readonly createBlobPayloadPending;
79
94
  constructor(props: {
80
95
  readonly routeContext: IFluidHandleContext;
81
96
  blobManagerLoadInfo: IBlobManagerLoadInfo;
@@ -103,10 +118,18 @@ export declare class BlobManager {
103
118
  private createAbortError;
104
119
  hasPendingStashedUploads(): boolean;
105
120
  hasBlob(blobId: string): boolean;
121
+ /**
122
+ * Retrieve the blob with the given local blob id.
123
+ * @param blobId - The local blob id. Likely coming from a handle.
124
+ * @param payloadPending - Whether we suspect the payload may be pending and not available yet.
125
+ * @returns A promise which resolves to the blob contents
126
+ */
106
127
  getBlob(blobId: string, payloadPending: boolean): Promise<ArrayBufferLike>;
107
128
  private getBlobHandle;
108
129
  private createBlobDetached;
109
- createBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<IFluidHandleInternal<ArrayBufferLike>>;
130
+ createBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<IFluidHandleInternalPayloadPending<ArrayBufferLike>>;
131
+ private createBlobLegacy;
132
+ private createBlobWithPayloadPending;
110
133
  private uploadBlob;
111
134
  /**
112
135
  * Set up a mapping in the redirect table from fromId to toId. Also, notify the runtime that a reference is added
@@ -1 +1 @@
1
- {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../../src/blobManager/blobManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,iBAAiB,EAGjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,MAAM,wDAAwD,CAAC;AAChE,OAAO,KAAK,EACX,MAAM,EACN,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,kCAAkC,EAClC,MAAM,0CAA0C,CAAC;AAElD,OAAO,EACN,uBAAuB,EACvB,mBAAmB,EACnB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACN,sBAAsB,EACtB,qBAAqB,EACrB,iBAAiB,EACjB,KAAK,yBAAyB,EAC9B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACN,eAAe,EAIf,MAAM,wCAAwC,CAAC;AAYhD,OAAO,EAIN,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,qBAAa,UACZ,SAAQ,eAAe,CAAC,eAAe,CACvC,YAAW,kCAAkC,CAAC,eAAe,CAAC;aAW7C,IAAI,EAAE,MAAM;aACZ,YAAY,EAAE,mBAAmB;IAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC;aAC1B,cAAc,EAAE,OAAO;IACvC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;IAbhC,OAAO,CAAC,QAAQ,CAAkB;IAElC,IAAW,UAAU,IAAI,OAAO,CAE/B;IAED,SAAgB,YAAY,EAAE,MAAM,CAAC;gBAGpB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,mBAAmB,EAC1C,GAAG,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,EAC1B,cAAc,EAAE,OAAO,EACtB,aAAa,CAAC,SAAQ,IAAI,aAAA;IAMrC,WAAW,IAAI,IAAI;IAOnB,IAAI,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;CAG/C;AAID,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACrC,iBAAiB,EACjB,aAAa,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe,GAAG,UAAU,CACzE,GACA,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;AAmB5C,MAAM,WAAW,aAAa;IAC7B,CAAC,OAAO,EAAE,MAAM,GAAG;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,KAAK,CAAC,EAAE,OAAO,CAAC;KAChB,CAAC;CACF;AAED,MAAM,WAAW,kBAAmB,SAAQ,MAAM;IACjD,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,IAAI,OAAE;CAChD;AAiBD,eAAO,MAAM,mBAAmB,UAAoB,CAAC;AAErD,qBAAa,WAAW;IACvB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IAEvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA+C;IAC5E,IAAW,MAAM,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAEtD;IACD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuD;IAEtF;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkC;IAEhE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuC;IAEpE;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IAEnE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAgD;IACjF,OAAO,CAAC,aAAa,CAAkB;IAEvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAGlD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAG3D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAe;IACpD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CACzB;IACX,SAAgB,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC;gBAE1D,KAAK,EAAE;QACzB,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;QAE3C,mBAAmB,EAAE,oBAAoB,CAAC;QAC1C,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC;QAC1C;;;;;;;;;WASG;QACH,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAGhE,QAAQ,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;QAGnD,QAAQ,CAAC,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QACtD,QAAQ,CAAC,OAAO,EAAE,mBAAmB,CAAC;QACtC,YAAY,EAAE,aAAa,GAAG,SAAS,CAAC;QACxC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;QAC3D,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC;KAC3C;IAwGD,IAAW,gBAAgB,IAAI,OAAO,CAOrC;IAED,IAAW,eAAe,IAAI,OAAO,CAKpC;IAED,OAAO,CAAC,gBAAgB;IAOjB,wBAAwB,IAAI,OAAO;IAInC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAI1B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC;IA4DvF,OAAO,CAAC,aAAa;YAwBP,kBAAkB;IAUnB,UAAU,CACtB,IAAI,EAAE,eAAe,EACrB,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;YA4CnC,UAAU;IA+CxB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAgEvB;;;;OAIG;IACI,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI;IAiB7D,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAqDlF,SAAS,CAAC,gBAAgB,CAAC,EAAE,iBAAiB,GAAG,qBAAqB;IAI7E;;;;;OAKG;IACI,SAAS,CAAC,MAAM,GAAE,OAAe,GAAG,sBAAsB;IAejE;;;;;OAKG;IACI,qBAAqB,CAAC,oBAAoB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE;IAKxF;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,4BAA4B;IA8CpC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqBrB,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAiBzD;;;;;;;;;OASG;IACU,wBAAwB,CACpC,uBAAuB,CAAC,EAAE,WAAW,GACnC,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;CA+ErC;AAmBD;;GAEG;AACH,eAAO,MAAM,UAAU,SAAU,MAAM,gCACL,CAAC"}
1
+ {"version":3,"file":"blobManager.d.ts","sourceRoot":"","sources":["../../src/blobManager/blobManager.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,15 @@ class BlobHandle extends internal_3.FluidHandleBase {
24
24
  get isAttached() {
25
25
  return this.routeContext.isAttached && this.attached;
26
26
  }
27
+ get events() {
28
+ return (this._events ??= (0, client_utils_1.createEmitter)());
29
+ }
30
+ get payloadState() {
31
+ return this._state;
32
+ }
33
+ get payloadShareError() {
34
+ return this._payloadShareError;
35
+ }
27
36
  constructor(path, routeContext, get, payloadPending, onAttachGraph) {
28
37
  super();
29
38
  this.path = path;
@@ -32,6 +41,15 @@ class BlobHandle extends internal_3.FluidHandleBase {
32
41
  this.payloadPending = payloadPending;
33
42
  this.onAttachGraph = onAttachGraph;
34
43
  this.attached = false;
44
+ this._state = "pending";
45
+ this.notifyShared = () => {
46
+ this._state = "shared";
47
+ this._events?.emit("payloadShared");
48
+ };
49
+ this.notifyFailed = (error) => {
50
+ this._payloadShareError = error;
51
+ this._events?.emit("payloadShareFailed", error);
52
+ };
35
53
  this.absolutePath = (0, internal_3.generateHandleContextPath)(path, this.routeContext);
36
54
  }
37
55
  attachGraph() {
@@ -40,6 +58,10 @@ class BlobHandle extends internal_3.FluidHandleBase {
40
58
  this.onAttachGraph?.();
41
59
  }
42
60
  }
61
+ // eslint-disable-next-line jsdoc/require-description
62
+ /**
63
+ * @deprecated No replacement provided. Arbitrary handles may not serve as a bind source.
64
+ */
43
65
  bind(handle) {
44
66
  throw new Error("Cannot bind to blob handle");
45
67
  }
@@ -57,8 +79,8 @@ class BlobManager {
57
79
  return this.publicEvents;
58
80
  }
59
81
  constructor(props) {
60
- this.publicEvents = new client_utils_1.TypedEventEmitter();
61
- this.internalEvents = new client_utils_1.TypedEventEmitter();
82
+ this.publicEvents = (0, client_utils_1.createEmitter)();
83
+ this.internalEvents = (0, client_utils_1.createEmitter)();
62
84
  /**
63
85
  * Blobs which we have not yet seen a BlobAttach op round-trip and not yet attached to a DDS.
64
86
  */
@@ -71,13 +93,14 @@ class BlobManager {
71
93
  this.opsInFlight = new Map();
72
94
  this.stopAttaching = false;
73
95
  this.pendingStashedBlobs = new Map();
74
- const { routeContext, blobManagerLoadInfo, storage, sendBlobAttachOp, blobRequested, isBlobDeleted, runtime, stashedBlobs, localBlobIdGenerator, } = props;
96
+ const { routeContext, blobManagerLoadInfo, storage, sendBlobAttachOp, blobRequested, isBlobDeleted, runtime, stashedBlobs, localBlobIdGenerator, createBlobPayloadPending, } = props;
75
97
  this.routeContext = routeContext;
76
98
  this.storage = storage;
77
99
  this.blobRequested = blobRequested;
78
100
  this.isBlobDeleted = isBlobDeleted;
79
101
  this.runtime = runtime;
80
102
  this.localBlobIdGenerator = localBlobIdGenerator ?? uuid_1.v4;
103
+ this.createBlobPayloadPending = createBlobPayloadPending;
81
104
  this.mc = (0, internal_4.createChildMonitoringContext)({
82
105
  logger: this.runtime.baseLogger,
83
106
  namespace: "BlobManager",
@@ -169,6 +192,12 @@ class BlobManager {
169
192
  hasBlob(blobId) {
170
193
  return this.redirectTable.get(blobId) !== undefined;
171
194
  }
195
+ /**
196
+ * Retrieve the blob with the given local blob id.
197
+ * @param blobId - The local blob id. Likely coming from a handle.
198
+ * @param payloadPending - Whether we suspect the payload may be pending and not available yet.
199
+ * @returns A promise which resolves to the blob contents
200
+ */
172
201
  async getBlob(blobId, payloadPending) {
173
202
  // Verify that the blob is not deleted, i.e., it has not been garbage collected. If it is, this will throw
174
203
  // an error, failing the call.
@@ -191,7 +220,9 @@ class BlobManager {
191
220
  else {
192
221
  const attachedStorageId = this.redirectTable.get(blobId);
193
222
  if (!payloadPending) {
194
- (0, internal_1.assert)(!!attachedStorageId, 0x11f /* "requesting unknown blobs" */);
223
+ // Only blob handles explicitly marked with pending payload are permitted to exist without
224
+ // yet knowing their storage id. Otherwise they must already be associated with a storage id.
225
+ (0, internal_1.assert)(attachedStorageId !== undefined, 0x11f /* "requesting unknown blobs" */);
195
226
  }
196
227
  // If we didn't find it in the redirectTable, assume the attach op is coming eventually and wait.
197
228
  // We do this even if the local client doesn't have the blob payloadPending flag enabled, in case a
@@ -222,11 +253,11 @@ class BlobManager {
222
253
  getBlobHandle(localId) {
223
254
  (0, internal_1.assert)(this.redirectTable.has(localId) || this.pendingBlobs.has(localId), 0x384 /* requesting handle for unknown blob */);
224
255
  const pending = this.pendingBlobs.get(localId);
225
- // Create a callback function for once the blob has been attached
256
+ // Create a callback function for once the handle has been attached
226
257
  const callback = pending
227
258
  ? () => {
228
259
  pending.attached = true;
229
- // Notify listeners (e.g. serialization process) that blob has been attached
260
+ // Notify listeners (e.g. serialization process) that handle has been attached
230
261
  this.internalEvents.emit("handleAttached", pending);
231
262
  this.deletePendingBlobMaybe(localId);
232
263
  }
@@ -251,6 +282,11 @@ class BlobManager {
251
282
  await new Promise((resolve) => this.runtime.once("attached", resolve));
252
283
  }
253
284
  (0, internal_1.assert)(this.runtime.attachState === container_definitions_1.AttachState.Attached, 0x385 /* For clarity and paranoid defense against adding future attachment states */);
285
+ return this.createBlobPayloadPending
286
+ ? this.createBlobWithPayloadPending(blob)
287
+ : this.createBlobLegacy(blob, signal);
288
+ }
289
+ async createBlobLegacy(blob, signal) {
254
290
  if (signal?.aborted) {
255
291
  throw this.createAbortError();
256
292
  }
@@ -277,6 +313,36 @@ class BlobManager {
277
313
  signal?.removeEventListener("abort", abortListener);
278
314
  });
279
315
  }
316
+ createBlobWithPayloadPending(blob) {
317
+ const localId = this.localBlobIdGenerator();
318
+ const blobHandle = new BlobHandle(getGCNodePathFromBlobId(localId), this.routeContext, async () => blob, true, // payloadPending
319
+ () => {
320
+ const pendingEntry = {
321
+ blob,
322
+ handleP: new internal_1.Deferred(),
323
+ uploadP: this.uploadBlob(localId, blob),
324
+ attached: true,
325
+ acked: false,
326
+ opsent: false,
327
+ };
328
+ this.pendingBlobs.set(localId, pendingEntry);
329
+ });
330
+ const onProcessedBlobAttach = (_localId, _storageId) => {
331
+ if (_localId === localId) {
332
+ this.internalEvents.off("processedBlobAttach", onProcessedBlobAttach);
333
+ blobHandle.notifyShared();
334
+ }
335
+ };
336
+ this.internalEvents.on("processedBlobAttach", onProcessedBlobAttach);
337
+ const onUploadFailed = (_localId, error) => {
338
+ if (_localId === localId) {
339
+ this.internalEvents.off("uploadFailed", onUploadFailed);
340
+ blobHandle.notifyFailed(error);
341
+ }
342
+ };
343
+ this.internalEvents.on("uploadFailed", onUploadFailed);
344
+ return blobHandle;
345
+ }
280
346
  async uploadBlob(localId, blob) {
281
347
  return (0, internal_2.runWithRetry)(async () => {
282
348
  try {
@@ -305,6 +371,7 @@ class BlobManager {
305
371
  // the promise but not throw any error outside.
306
372
  this.pendingBlobs.get(localId)?.handleP.reject(error);
307
373
  this.deletePendingBlob(localId);
374
+ this.internalEvents.emit("uploadFailed", localId, error);
308
375
  });
309
376
  }
310
377
  /**
@@ -366,7 +433,9 @@ class BlobManager {
366
433
  // an existing blob, we don't have to wait for the op to be ack'd since this step has already
367
434
  // happened before and so, the server won't delete it.
368
435
  this.setRedirection(localId, response.id);
369
- entry.handleP.resolve(this.getBlobHandle(localId));
436
+ const blobHandle = this.getBlobHandle(localId);
437
+ blobHandle.notifyShared();
438
+ entry.handleP.resolve(blobHandle);
370
439
  this.deletePendingBlobMaybe(localId);
371
440
  }
372
441
  else {
@@ -421,8 +490,8 @@ class BlobManager {
421
490
  }
422
491
  // set identity (id -> id) entry
423
492
  this.setRedirection(blobId, blobId);
493
+ (0, internal_1.assert)(localId !== undefined, 0x50e /* local ID not present in blob attach message */);
424
494
  if (local) {
425
- (0, internal_1.assert)(localId !== undefined, 0x50e /* local ID not present in blob attach message */);
426
495
  const waitingBlobs = this.opsInFlight.get(blobId);
427
496
  if (waitingBlobs !== undefined) {
428
497
  // For each op corresponding to this storage ID that we are waiting for, resolve the pending blob.
@@ -433,7 +502,9 @@ class BlobManager {
433
502
  (0, internal_1.assert)(entry !== undefined, 0x38f /* local online BlobAttach op with no pending blob entry */);
434
503
  this.setRedirection(pendingLocalId, blobId);
435
504
  entry.acked = true;
436
- entry.handleP.resolve(this.getBlobHandle(pendingLocalId));
505
+ const blobHandle = this.getBlobHandle(pendingLocalId);
506
+ blobHandle.notifyShared();
507
+ entry.handleP.resolve(blobHandle);
437
508
  this.deletePendingBlobMaybe(pendingLocalId);
438
509
  }
439
510
  this.opsInFlight.delete(blobId);
@@ -441,7 +512,9 @@ class BlobManager {
441
512
  const localEntry = this.pendingBlobs.get(localId);
442
513
  if (localEntry) {
443
514
  localEntry.acked = true;
444
- localEntry.handleP.resolve(this.getBlobHandle(localId));
515
+ const blobHandle = this.getBlobHandle(localId);
516
+ blobHandle.notifyShared();
517
+ localEntry.handleP.resolve(blobHandle);
445
518
  this.deletePendingBlobMaybe(localId);
446
519
  }
447
520
  }
@@ -583,7 +656,7 @@ class BlobManager {
583
656
  const localBlobs = new Set();
584
657
  // This while is used to stash blobs created while attaching and getting blobs
585
658
  while (localBlobs.size < this.pendingBlobs.size) {
586
- const attachBlobsP = [];
659
+ const attachHandlesP = [];
587
660
  for (const [localId, entry] of this.pendingBlobs) {
588
661
  if (!localBlobs.has(entry)) {
589
662
  localBlobs.add(entry);
@@ -598,15 +671,15 @@ class BlobManager {
598
671
  // original createBlob call) and let them attach the blob. This is a lie we told since the upload
599
672
  // hasn't finished yet, but it's fine since we will retry on rehydration.
600
673
  entry.handleP.resolve(this.getBlobHandle(localId));
601
- // Array of promises that will resolve when blobs get attached.
602
- attachBlobsP.push(new Promise((resolve, reject) => {
674
+ // Array of promises that will resolve when handles get attached.
675
+ attachHandlesP.push(new Promise((resolve, reject) => {
603
676
  stopBlobAttachingSignal?.addEventListener("abort", () => {
604
677
  this.stopAttaching = true;
605
678
  reject(new Error("Operation aborted"));
606
679
  }, { once: true });
607
- const onBlobAttached = (attachedEntry) => {
680
+ const onHandleAttached = (attachedEntry) => {
608
681
  if (attachedEntry === entry) {
609
- this.internalEvents.off("handleAttached", onBlobAttached);
682
+ this.internalEvents.off("handleAttached", onHandleAttached);
610
683
  resolve();
611
684
  }
612
685
  };
@@ -614,14 +687,14 @@ class BlobManager {
614
687
  resolve();
615
688
  }
616
689
  else {
617
- this.internalEvents.on("handleAttached", onBlobAttached);
690
+ this.internalEvents.on("handleAttached", onHandleAttached);
618
691
  }
619
692
  }));
620
693
  }
621
694
  }
622
695
  // Wait for all blobs to be attached. This is important, otherwise serialized container
623
696
  // could send the blobAttach op without any op that references the blob, making it useless.
624
- await Promise.allSettled(attachBlobsP);
697
+ await Promise.allSettled(attachHandlesP);
625
698
  }
626
699
  for (const [localId, entry] of this.pendingBlobs) {
627
700
  if (stopBlobAttachingSignal?.aborted && !entry.attached) {