@fluidframework/container-loader 2.0.0-dev.2.3.0.115467 → 2.0.0-dev.4.1.0.148229

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 (168) hide show
  1. package/.eslintrc.js +18 -21
  2. package/.mocharc.js +2 -2
  3. package/README.md +65 -44
  4. package/api-extractor.json +2 -2
  5. package/closeAndGetPendingLocalState.md +51 -0
  6. package/dist/audience.d.ts +0 -1
  7. package/dist/audience.d.ts.map +1 -1
  8. package/dist/audience.js.map +1 -1
  9. package/dist/catchUpMonitor.d.ts.map +1 -1
  10. package/dist/catchUpMonitor.js.map +1 -1
  11. package/dist/collabWindowTracker.d.ts.map +1 -1
  12. package/dist/collabWindowTracker.js.map +1 -1
  13. package/dist/connectionManager.d.ts +5 -5
  14. package/dist/connectionManager.d.ts.map +1 -1
  15. package/dist/connectionManager.js +107 -44
  16. package/dist/connectionManager.js.map +1 -1
  17. package/dist/connectionState.d.ts.map +1 -1
  18. package/dist/connectionState.js.map +1 -1
  19. package/dist/connectionStateHandler.d.ts +7 -7
  20. package/dist/connectionStateHandler.d.ts.map +1 -1
  21. package/dist/connectionStateHandler.js +50 -21
  22. package/dist/connectionStateHandler.js.map +1 -1
  23. package/dist/container.d.ts +64 -5
  24. package/dist/container.d.ts.map +1 -1
  25. package/dist/container.js +329 -137
  26. package/dist/container.js.map +1 -1
  27. package/dist/containerContext.d.ts +19 -8
  28. package/dist/containerContext.d.ts.map +1 -1
  29. package/dist/containerContext.js +58 -14
  30. package/dist/containerContext.js.map +1 -1
  31. package/dist/containerStorageAdapter.d.ts +41 -2
  32. package/dist/containerStorageAdapter.d.ts.map +1 -1
  33. package/dist/containerStorageAdapter.js +88 -14
  34. package/dist/containerStorageAdapter.js.map +1 -1
  35. package/dist/contracts.d.ts +3 -3
  36. package/dist/contracts.d.ts.map +1 -1
  37. package/dist/contracts.js.map +1 -1
  38. package/dist/deltaManager.d.ts +21 -8
  39. package/dist/deltaManager.d.ts.map +1 -1
  40. package/dist/deltaManager.js +112 -37
  41. package/dist/deltaManager.js.map +1 -1
  42. package/dist/deltaManagerProxy.d.ts +10 -22
  43. package/dist/deltaManagerProxy.d.ts.map +1 -1
  44. package/dist/deltaManagerProxy.js +14 -50
  45. package/dist/deltaManagerProxy.js.map +1 -1
  46. package/dist/deltaQueue.d.ts.map +1 -1
  47. package/dist/deltaQueue.js +4 -2
  48. package/dist/deltaQueue.js.map +1 -1
  49. package/dist/index.d.ts +4 -3
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +1 -3
  52. package/dist/index.js.map +1 -1
  53. package/dist/loader.d.ts +13 -4
  54. package/dist/loader.d.ts.map +1 -1
  55. package/dist/loader.js +38 -24
  56. package/dist/loader.js.map +1 -1
  57. package/dist/packageVersion.d.ts +1 -1
  58. package/dist/packageVersion.js +1 -1
  59. package/dist/packageVersion.js.map +1 -1
  60. package/dist/protocol.d.ts.map +1 -1
  61. package/dist/protocol.js +2 -1
  62. package/dist/protocol.js.map +1 -1
  63. package/dist/protocolTreeDocumentStorageService.d.ts +6 -2
  64. package/dist/protocolTreeDocumentStorageService.d.ts.map +1 -1
  65. package/dist/protocolTreeDocumentStorageService.js +7 -4
  66. package/dist/protocolTreeDocumentStorageService.js.map +1 -1
  67. package/dist/quorum.d.ts.map +1 -1
  68. package/dist/quorum.js.map +1 -1
  69. package/dist/retriableDocumentStorageService.d.ts.map +1 -1
  70. package/dist/retriableDocumentStorageService.js +6 -2
  71. package/dist/retriableDocumentStorageService.js.map +1 -1
  72. package/dist/utils.d.ts.map +1 -1
  73. package/dist/utils.js +8 -5
  74. package/dist/utils.js.map +1 -1
  75. package/lib/audience.d.ts +0 -1
  76. package/lib/audience.d.ts.map +1 -1
  77. package/lib/audience.js.map +1 -1
  78. package/lib/catchUpMonitor.d.ts.map +1 -1
  79. package/lib/catchUpMonitor.js.map +1 -1
  80. package/lib/collabWindowTracker.d.ts.map +1 -1
  81. package/lib/collabWindowTracker.js.map +1 -1
  82. package/lib/connectionManager.d.ts +5 -5
  83. package/lib/connectionManager.d.ts.map +1 -1
  84. package/lib/connectionManager.js +110 -47
  85. package/lib/connectionManager.js.map +1 -1
  86. package/lib/connectionState.d.ts.map +1 -1
  87. package/lib/connectionState.js.map +1 -1
  88. package/lib/connectionStateHandler.d.ts +7 -7
  89. package/lib/connectionStateHandler.d.ts.map +1 -1
  90. package/lib/connectionStateHandler.js +50 -21
  91. package/lib/connectionStateHandler.js.map +1 -1
  92. package/lib/container.d.ts +64 -5
  93. package/lib/container.d.ts.map +1 -1
  94. package/lib/container.js +336 -144
  95. package/lib/container.js.map +1 -1
  96. package/lib/containerContext.d.ts +19 -8
  97. package/lib/containerContext.d.ts.map +1 -1
  98. package/lib/containerContext.js +59 -15
  99. package/lib/containerContext.js.map +1 -1
  100. package/lib/containerStorageAdapter.d.ts +41 -2
  101. package/lib/containerStorageAdapter.d.ts.map +1 -1
  102. package/lib/containerStorageAdapter.js +86 -14
  103. package/lib/containerStorageAdapter.js.map +1 -1
  104. package/lib/contracts.d.ts +3 -3
  105. package/lib/contracts.d.ts.map +1 -1
  106. package/lib/contracts.js.map +1 -1
  107. package/lib/deltaManager.d.ts +21 -8
  108. package/lib/deltaManager.d.ts.map +1 -1
  109. package/lib/deltaManager.js +114 -39
  110. package/lib/deltaManager.js.map +1 -1
  111. package/lib/deltaManagerProxy.d.ts +10 -22
  112. package/lib/deltaManagerProxy.d.ts.map +1 -1
  113. package/lib/deltaManagerProxy.js +14 -50
  114. package/lib/deltaManagerProxy.js.map +1 -1
  115. package/lib/deltaQueue.d.ts.map +1 -1
  116. package/lib/deltaQueue.js +4 -2
  117. package/lib/deltaQueue.js.map +1 -1
  118. package/lib/index.d.ts +4 -3
  119. package/lib/index.d.ts.map +1 -1
  120. package/lib/index.js +2 -2
  121. package/lib/index.js.map +1 -1
  122. package/lib/loader.d.ts +13 -4
  123. package/lib/loader.d.ts.map +1 -1
  124. package/lib/loader.js +37 -24
  125. package/lib/loader.js.map +1 -1
  126. package/lib/packageVersion.d.ts +1 -1
  127. package/lib/packageVersion.js +1 -1
  128. package/lib/packageVersion.js.map +1 -1
  129. package/lib/protocol.d.ts.map +1 -1
  130. package/lib/protocol.js +2 -1
  131. package/lib/protocol.js.map +1 -1
  132. package/lib/protocolTreeDocumentStorageService.d.ts +6 -2
  133. package/lib/protocolTreeDocumentStorageService.d.ts.map +1 -1
  134. package/lib/protocolTreeDocumentStorageService.js +7 -4
  135. package/lib/protocolTreeDocumentStorageService.js.map +1 -1
  136. package/lib/quorum.d.ts.map +1 -1
  137. package/lib/quorum.js.map +1 -1
  138. package/lib/retriableDocumentStorageService.d.ts.map +1 -1
  139. package/lib/retriableDocumentStorageService.js +6 -2
  140. package/lib/retriableDocumentStorageService.js.map +1 -1
  141. package/lib/utils.d.ts.map +1 -1
  142. package/lib/utils.js +8 -5
  143. package/lib/utils.js.map +1 -1
  144. package/package.json +67 -56
  145. package/prettier.config.cjs +1 -1
  146. package/src/audience.ts +51 -46
  147. package/src/catchUpMonitor.ts +39 -37
  148. package/src/collabWindowTracker.ts +75 -70
  149. package/src/connectionManager.ts +1040 -941
  150. package/src/connectionState.ts +19 -19
  151. package/src/connectionStateHandler.ts +557 -463
  152. package/src/container.ts +2147 -1784
  153. package/src/containerContext.ts +417 -345
  154. package/src/containerStorageAdapter.ts +268 -154
  155. package/src/contracts.ts +155 -153
  156. package/src/deltaManager.ts +1074 -945
  157. package/src/deltaManagerProxy.ts +88 -137
  158. package/src/deltaQueue.ts +155 -151
  159. package/src/index.ts +13 -17
  160. package/src/loader.ts +434 -427
  161. package/src/packageVersion.ts +1 -1
  162. package/src/protocol.ts +93 -87
  163. package/src/protocolTreeDocumentStorageService.ts +34 -34
  164. package/src/quorum.ts +34 -34
  165. package/src/retriableDocumentStorageService.ts +118 -102
  166. package/src/utils.ts +93 -83
  167. package/tsconfig.esnext.json +6 -6
  168. package/tsconfig.json +8 -12
@@ -3,7 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  import { ITelemetryLogger } from "@fluidframework/common-definitions";
6
- import { IAudience, IContainerContext, IDeltaManager, ILoader, ICriticalContainerError, AttachState, ILoaderOptions, IFluidCodeDetails, ICodeDetailsLoader, ISnapshotTreeWithBlobContents, IBatchMessage } from "@fluidframework/container-definitions";
6
+ import { IAudience, IContainerContext, IDeltaManager, ILoader, ICriticalContainerError, AttachState, ILoaderOptions, IFluidCodeDetails, ICodeDetailsLoader, IBatchMessage } from "@fluidframework/container-definitions";
7
7
  import { IRequest, IResponse, FluidObject } from "@fluidframework/core-interfaces";
8
8
  import { IDocumentStorageService } from "@fluidframework/driver-definitions";
9
9
  import { IClientConfiguration, IClientDetails, IDocumentMessage, IQuorum, IQuorumClients, ISequencedDocumentMessage, ISignalMessage, ISnapshotTree, ISummaryTree, IVersion, MessageType, ISummaryContent } from "@fluidframework/protocol-definitions";
@@ -13,21 +13,23 @@ export declare class ContainerContext implements IContainerContext {
13
13
  readonly scope: FluidObject;
14
14
  private readonly codeLoader;
15
15
  private readonly _codeDetails;
16
- private _baseSnapshot;
16
+ private readonly _baseSnapshot;
17
17
  readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
18
18
  readonly loader: ILoader;
19
19
  readonly submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number;
20
- readonly submitSummaryFn: (summaryOp: ISummaryContent) => number;
20
+ readonly submitSummaryFn: (summaryOp: ISummaryContent, referenceSequenceNumber?: number) => number;
21
21
  /** @returns clientSequenceNumber of last message in a batch */
22
- readonly submitBatchFn: (batch: IBatchMessage[]) => number;
22
+ readonly submitBatchFn: (batch: IBatchMessage[], referenceSequenceNumber?: number) => number;
23
23
  readonly submitSignalFn: (contents: any) => void;
24
+ readonly disposeFn: (error?: ICriticalContainerError) => void;
24
25
  readonly closeFn: (error?: ICriticalContainerError) => void;
25
26
  readonly version: string;
26
27
  readonly updateDirtyContainerState: (dirty: boolean) => void;
27
28
  readonly existing: boolean;
28
29
  readonly pendingLocalState?: unknown;
29
- static createOrLoad(container: Container, scope: FluidObject, codeLoader: ICodeDetailsLoader, codeDetails: IFluidCodeDetails, baseSnapshot: ISnapshotTree | undefined, deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>, quorum: IQuorum, loader: ILoader, submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number, submitSummaryFn: (summaryOp: ISummaryContent) => number, submitBatchFn: (batch: IBatchMessage[]) => number, submitSignalFn: (contents: any) => void, closeFn: (error?: ICriticalContainerError) => void, version: string, updateDirtyContainerState: (dirty: boolean) => void, existing: boolean, pendingLocalState?: unknown): Promise<ContainerContext>;
30
+ static createOrLoad(container: Container, scope: FluidObject, codeLoader: ICodeDetailsLoader, codeDetails: IFluidCodeDetails, baseSnapshot: ISnapshotTree | undefined, deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>, quorum: IQuorum, loader: ILoader, submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number, submitSummaryFn: (summaryOp: ISummaryContent, referenceSequenceNumber?: number) => number, submitBatchFn: (batch: IBatchMessage[], referenceSequenceNumber?: number) => number, submitSignalFn: (contents: any) => void, disposeFn: (error?: ICriticalContainerError) => void, closeFn: (error?: ICriticalContainerError) => void, version: string, updateDirtyContainerState: (dirty: boolean) => void, existing: boolean, pendingLocalState?: unknown): Promise<ContainerContext>;
30
31
  readonly taggedLogger: ITelemetryLogger;
32
+ readonly supportedFeatures: ReadonlyMap<string, unknown>;
31
33
  get clientId(): string | undefined;
32
34
  /**
33
35
  * DISCLAIMER: this id is only for telemetry purposes. Not suitable for any other usages.
@@ -54,9 +56,18 @@ export declare class ContainerContext implements IContainerContext {
54
56
  private readonly _quorum;
55
57
  get quorum(): IQuorumClients;
56
58
  private readonly _fluidModuleP;
57
- constructor(container: Container, scope: FluidObject, codeLoader: ICodeDetailsLoader, _codeDetails: IFluidCodeDetails, _baseSnapshot: ISnapshotTree | undefined, deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>, quorum: IQuorum, loader: ILoader, submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number, submitSummaryFn: (summaryOp: ISummaryContent) => number,
59
+ /**
60
+ * {@inheritDoc @fluidframework/container-definitions#IContainerContext.getEntryPoint}
61
+ */
62
+ getEntryPoint?(): Promise<FluidObject | undefined>;
63
+ /**
64
+ * Emits events about the container context's lifecycle.
65
+ * Use it to coordinate things inside the ContainerContext class.
66
+ */
67
+ private readonly lifecycleEvents;
68
+ constructor(container: Container, scope: FluidObject, codeLoader: ICodeDetailsLoader, _codeDetails: IFluidCodeDetails, _baseSnapshot: ISnapshotTree | undefined, deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>, quorum: IQuorum, loader: ILoader, submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number, submitSummaryFn: (summaryOp: ISummaryContent, referenceSequenceNumber?: number) => number,
58
69
  /** @returns clientSequenceNumber of last message in a batch */
59
- submitBatchFn: (batch: IBatchMessage[]) => number, submitSignalFn: (contents: any) => void, closeFn: (error?: ICriticalContainerError) => void, version: string, updateDirtyContainerState: (dirty: boolean) => void, existing: boolean, pendingLocalState?: unknown);
70
+ submitBatchFn: (batch: IBatchMessage[], referenceSequenceNumber?: number) => number, submitSignalFn: (contents: any) => void, disposeFn: (error?: ICriticalContainerError) => void, closeFn: (error?: ICriticalContainerError) => void, version: string, updateDirtyContainerState: (dirty: boolean) => void, existing: boolean, pendingLocalState?: unknown);
60
71
  /**
61
72
  * @deprecated Temporary migratory API, to be removed when customers no longer need it.
62
73
  * When removed, `ContainerContext` should only take an {@link @fluidframework/container-definitions#IQuorumClients}
@@ -86,7 +97,7 @@ export declare class ContainerContext implements IContainerContext {
86
97
  * satisfy the incoming constraint code details
87
98
  */
88
99
  satisfies(constraintCodeDetails: IFluidCodeDetails): Promise<boolean>;
89
- notifyAttaching(snapshot: ISnapshotTreeWithBlobContents): void;
100
+ notifyOpReplay(message: ISequencedDocumentMessage): Promise<void>;
90
101
  private getRuntimeFactory;
91
102
  private instantiateRuntime;
92
103
  private attachListener;
@@ -1 +1 @@
1
- {"version":3,"file":"containerContext.d.ts","sourceRoot":"","sources":["../src/containerContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"containerContext.d.ts","sourceRoot":"","sources":["../src/containerContext.ts"],"names":[],"mappings":"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"}
@@ -2,16 +2,16 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { LazyPromise } from "@fluidframework/common-utils";
5
+ import { assert, LazyPromise, TypedEventEmitter } from "@fluidframework/common-utils";
6
6
  import { AttachState, } from "@fluidframework/container-definitions";
7
7
  import { isFluidResolvedUrl } from "@fluidframework/driver-utils";
8
8
  import { PerformanceEvent } from "@fluidframework/telemetry-utils";
9
- import { ReportIfTooLong } from "./container";
9
+ import { UsageError } from "@fluidframework/container-utils";
10
10
  const PackageNotFactoryError = "Code package does not implement IRuntimeFactory";
11
11
  export class ContainerContext {
12
12
  constructor(container, scope, codeLoader, _codeDetails, _baseSnapshot, deltaManager, quorum, loader, submitFn, submitSummaryFn,
13
13
  /** @returns clientSequenceNumber of last message in a batch */
14
- submitBatchFn, submitSignalFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState) {
14
+ submitBatchFn, submitSignalFn, disposeFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState) {
15
15
  this.container = container;
16
16
  this.scope = scope;
17
17
  this.codeLoader = codeLoader;
@@ -23,20 +23,34 @@ export class ContainerContext {
23
23
  this.submitSummaryFn = submitSummaryFn;
24
24
  this.submitBatchFn = submitBatchFn;
25
25
  this.submitSignalFn = submitSignalFn;
26
+ this.disposeFn = disposeFn;
26
27
  this.closeFn = closeFn;
27
28
  this.version = version;
28
29
  this.updateDirtyContainerState = updateDirtyContainerState;
29
30
  this.existing = existing;
30
31
  this.pendingLocalState = pendingLocalState;
31
32
  this._disposed = false;
33
+ /**
34
+ * Emits events about the container context's lifecycle.
35
+ * Use it to coordinate things inside the ContainerContext class.
36
+ */
37
+ this.lifecycleEvents = new TypedEventEmitter();
32
38
  this._connected = this.container.connected;
33
39
  this._quorum = quorum;
34
40
  this.taggedLogger = container.subLogger;
35
41
  this._fluidModuleP = new LazyPromise(async () => this.loadCodeModule(_codeDetails));
42
+ this.supportedFeatures = new Map([
43
+ /**
44
+ * This version of the loader accepts `referenceSequenceNumber`, provided by the container runtime,
45
+ * as a parameter to the `submitBatchFn` and `submitSummaryFn` functions.
46
+ * This is then used to set the reference sequence numbers of the submitted ops in the DeltaManager.
47
+ */
48
+ ["referenceSequenceNumbers", true],
49
+ ]);
36
50
  this.attachListener();
37
51
  }
38
- static async createOrLoad(container, scope, codeLoader, codeDetails, baseSnapshot, deltaManager, quorum, loader, submitFn, submitSummaryFn, submitBatchFn, submitSignalFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState) {
39
- const context = new ContainerContext(container, scope, codeLoader, codeDetails, baseSnapshot, deltaManager, quorum, loader, submitFn, submitSummaryFn, submitBatchFn, submitSignalFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState);
52
+ static async createOrLoad(container, scope, codeLoader, codeDetails, baseSnapshot, deltaManager, quorum, loader, submitFn, submitSummaryFn, submitBatchFn, submitSignalFn, disposeFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState) {
53
+ const context = new ContainerContext(container, scope, codeLoader, codeDetails, baseSnapshot, deltaManager, quorum, loader, submitFn, submitSummaryFn, submitBatchFn, submitSignalFn, disposeFn, closeFn, version, updateDirtyContainerState, existing, pendingLocalState);
40
54
  await context.instantiateRuntime(existing);
41
55
  return context;
42
56
  }
@@ -90,8 +104,38 @@ export class ContainerContext {
90
104
  get disposed() {
91
105
  return this._disposed;
92
106
  }
93
- get codeDetails() { return this._codeDetails; }
94
- get quorum() { return this._quorum; }
107
+ get codeDetails() {
108
+ return this._codeDetails;
109
+ }
110
+ get quorum() {
111
+ return this._quorum;
112
+ }
113
+ /**
114
+ * {@inheritDoc @fluidframework/container-definitions#IContainerContext.getEntryPoint}
115
+ */
116
+ async getEntryPoint() {
117
+ var _a, _b;
118
+ if (this._disposed) {
119
+ throw new UsageError("The context is already disposed");
120
+ }
121
+ if (this._runtime !== undefined) {
122
+ return (_b = (_a = this._runtime) === null || _a === void 0 ? void 0 : _a.getEntryPoint) === null || _b === void 0 ? void 0 : _b.call(_a);
123
+ }
124
+ return new Promise((resolve, reject) => {
125
+ const runtimeInstantiatedHandler = () => {
126
+ var _a, _b;
127
+ assert(this._runtime !== undefined, 0x5a3 /* runtimeInstantiated fired but runtime is still undefined */);
128
+ resolve((_b = (_a = this._runtime).getEntryPoint) === null || _b === void 0 ? void 0 : _b.call(_a));
129
+ this.lifecycleEvents.off("disposed", disposedHandler);
130
+ };
131
+ const disposedHandler = () => {
132
+ reject(new Error("ContainerContext was disposed"));
133
+ this.lifecycleEvents.off("runtimeInstantiated", runtimeInstantiatedHandler);
134
+ };
135
+ this.lifecycleEvents.once("runtimeInstantiated", runtimeInstantiatedHandler);
136
+ this.lifecycleEvents.once("disposed", disposedHandler);
137
+ });
138
+ }
95
139
  /**
96
140
  * @deprecated Temporary migratory API, to be removed when customers no longer need it.
97
141
  * When removed, `ContainerContext` should only take an {@link @fluidframework/container-definitions#IQuorumClients}
@@ -107,6 +151,7 @@ export class ContainerContext {
107
151
  return;
108
152
  }
109
153
  this._disposed = true;
154
+ this.lifecycleEvents.emit("disposed");
110
155
  this.runtime.dispose(error);
111
156
  this._quorum.dispose();
112
157
  this.deltaManager.dispose();
@@ -179,11 +224,9 @@ export class ContainerContext {
179
224
  }
180
225
  return true;
181
226
  }
182
- notifyAttaching(snapshot) {
227
+ async notifyOpReplay(message) {
183
228
  var _a, _b;
184
- this._baseSnapshot = snapshot;
185
- (_b = (_a = this.runtime).notifyAttaching) === null || _b === void 0 ? void 0 : _b.call(_a, snapshot);
186
- this.runtime.setAttachState(AttachState.Attaching);
229
+ return (_b = (_a = this.runtime).notifyOpReplay) === null || _b === void 0 ? void 0 : _b.call(_a, message);
187
230
  }
188
231
  // #region private
189
232
  async getRuntimeFactory() {
@@ -197,12 +240,13 @@ export class ContainerContext {
197
240
  }
198
241
  async instantiateRuntime(existing) {
199
242
  const runtimeFactory = await this.getRuntimeFactory();
200
- await ReportIfTooLong(this.taggedLogger, "instantiateRuntime", async () => {
201
- this._runtime = await runtimeFactory.instantiateRuntime(this, existing);
202
- return {};
203
- });
243
+ this._runtime = await PerformanceEvent.timedExecAsync(this.taggedLogger, { eventName: "InstantiateRuntime" }, async () => runtimeFactory.instantiateRuntime(this, existing));
244
+ this.lifecycleEvents.emit("runtimeInstantiated");
204
245
  }
205
246
  attachListener() {
247
+ this.container.once("attaching", () => {
248
+ this.runtime.setAttachState(AttachState.Attaching);
249
+ });
206
250
  this.container.once("attached", () => {
207
251
  this.runtime.setAttachState(AttachState.Attached);
208
252
  });
@@ -1 +1 @@
1
- {"version":3,"file":"containerContext.js","sourceRoot":"","sources":["../src/containerContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { LazyPromise } from \"@fluidframework/common-utils\";\nimport {\n IAudience,\n IContainerContext,\n IDeltaManager,\n ILoader,\n IRuntime,\n ICriticalContainerError,\n AttachState,\n ILoaderOptions,\n IRuntimeFactory,\n IProvideRuntimeFactory,\n IFluidCodeDetails,\n IFluidCodeDetailsComparer,\n IProvideFluidCodeDetailsComparer,\n ICodeDetailsLoader,\n IFluidModuleWithDetails,\n ISnapshotTreeWithBlobContents,\n IBatchMessage,\n} from \"@fluidframework/container-definitions\";\nimport {\n IRequest,\n IResponse,\n FluidObject,\n} from \"@fluidframework/core-interfaces\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { isFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport {\n IClientConfiguration,\n IClientDetails,\n IDocumentMessage,\n IQuorum,\n IQuorumClients,\n ISequencedDocumentMessage,\n ISignalMessage,\n ISnapshotTree,\n ISummaryTree,\n IVersion,\n MessageType,\n ISummaryContent,\n} from \"@fluidframework/protocol-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { Container, ReportIfTooLong } from \"./container\";\n\nconst PackageNotFactoryError = \"Code package does not implement IRuntimeFactory\";\n\nexport class ContainerContext implements IContainerContext {\n public static async createOrLoad(\n container: Container,\n scope: FluidObject,\n codeLoader: ICodeDetailsLoader,\n codeDetails: IFluidCodeDetails,\n baseSnapshot: ISnapshotTree | undefined,\n deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n quorum: IQuorum,\n loader: ILoader,\n submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number,\n submitSummaryFn: (summaryOp: ISummaryContent) => number,\n submitBatchFn: (batch: IBatchMessage[]) => number,\n submitSignalFn: (contents: any) => void,\n closeFn: (error?: ICriticalContainerError) => void,\n version: string,\n updateDirtyContainerState: (dirty: boolean) => void,\n existing: boolean,\n pendingLocalState?: unknown,\n ): Promise<ContainerContext> {\n const context = new ContainerContext(\n container,\n scope,\n codeLoader,\n codeDetails,\n baseSnapshot,\n deltaManager,\n quorum,\n loader,\n submitFn,\n submitSummaryFn,\n submitBatchFn,\n submitSignalFn,\n closeFn,\n version,\n updateDirtyContainerState,\n existing,\n pendingLocalState);\n await context.instantiateRuntime(existing);\n return context;\n }\n\n public readonly taggedLogger: ITelemetryLogger;\n\n public get clientId(): string | undefined {\n return this.container.clientId;\n }\n\n /**\n * DISCLAIMER: this id is only for telemetry purposes. Not suitable for any other usages.\n */\n public get id(): string {\n const resolvedUrl = this.container.resolvedUrl;\n if (isFluidResolvedUrl(resolvedUrl)) {\n return resolvedUrl.id;\n }\n return \"\";\n }\n\n public get clientDetails(): IClientDetails {\n return this.container.clientDetails;\n }\n\n private _connected: boolean;\n /**\n * When true, ops are free to flow\n * When false, ops should be kept as pending or rejected\n */\n public get connected(): boolean {\n return this._connected;\n }\n\n public get canSummarize(): boolean {\n return \"summarize\" in this.runtime;\n }\n\n public get serviceConfiguration(): IClientConfiguration | undefined {\n return this.container.serviceConfiguration;\n }\n\n public get audience(): IAudience {\n return this.container.audience;\n }\n\n public get options(): ILoaderOptions {\n return this.container.options;\n }\n\n public get baseSnapshot() {\n return this._baseSnapshot;\n }\n\n public get storage(): IDocumentStorageService {\n return this.container.storage;\n }\n\n private _runtime: IRuntime | undefined;\n private get runtime() {\n if (this._runtime === undefined) {\n throw new Error(\"Attempted to access runtime before it was defined\");\n }\n return this._runtime;\n }\n\n private _disposed = false;\n\n public get disposed() {\n return this._disposed;\n }\n\n public get codeDetails() { return this._codeDetails; }\n\n private readonly _quorum: IQuorum;\n public get quorum(): IQuorumClients { return this._quorum; }\n\n private readonly _fluidModuleP: Promise<IFluidModuleWithDetails>;\n\n constructor(\n private readonly container: Container,\n public readonly scope: FluidObject,\n private readonly codeLoader: ICodeDetailsLoader,\n private readonly _codeDetails: IFluidCodeDetails,\n private _baseSnapshot: ISnapshotTree | undefined,\n public readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n quorum: IQuorum,\n public readonly loader: ILoader,\n public readonly submitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number,\n public readonly submitSummaryFn: (summaryOp: ISummaryContent) => number,\n /** @returns clientSequenceNumber of last message in a batch */\n public readonly submitBatchFn: (batch: IBatchMessage[]) => number,\n public readonly submitSignalFn: (contents: any) => void,\n public readonly closeFn: (error?: ICriticalContainerError) => void,\n public readonly version: string,\n public readonly updateDirtyContainerState: (dirty: boolean) => void,\n public readonly existing: boolean,\n public readonly pendingLocalState?: unknown,\n\n ) {\n this._connected = this.container.connected;\n this._quorum = quorum;\n this.taggedLogger = container.subLogger;\n this._fluidModuleP = new LazyPromise<IFluidModuleWithDetails>(\n async () => this.loadCodeModule(_codeDetails),\n );\n this.attachListener();\n }\n\n /**\n * @deprecated Temporary migratory API, to be removed when customers no longer need it.\n * When removed, `ContainerContext` should only take an {@link @fluidframework/container-definitions#IQuorumClients}\n * rather than an {@link @fluidframework/protocol-definitions#IQuorum}.\n * See {@link @fluidframework/container-definitions#IContainerContext} for more details.\n */\n public getSpecifiedCodeDetails(): IFluidCodeDetails | undefined {\n return (this._quorum.get(\"code\") ?? this._quorum.get(\"code2\")) as IFluidCodeDetails | undefined;\n }\n\n public dispose(error?: Error): void {\n if (this._disposed) {\n return;\n }\n this._disposed = true;\n\n this.runtime.dispose(error);\n this._quorum.dispose();\n this.deltaManager.dispose();\n }\n\n public getLoadedFromVersion(): IVersion | undefined {\n return this.container.loadedFromVersion;\n }\n\n public get attachState(): AttachState {\n return this.container.attachState;\n }\n\n /**\n * Create a summary. Used when attaching or serializing a detached container.\n *\n * @param blobRedirectTable - A table passed during the attach process. While detached, blob upload is supported\n * using IDs generated locally. After attach, these IDs cannot be used, so this table maps the old local IDs to the\n * new storage IDs so requests can be redirected.\n */\n public createSummary(blobRedirectTable?: Map<string, string>): ISummaryTree {\n return this.runtime.createSummary(blobRedirectTable);\n }\n\n public setConnectionState(connected: boolean, clientId?: string) {\n const runtime = this.runtime;\n this._connected = connected;\n runtime.setConnectionState(connected, clientId);\n }\n\n public process(message: ISequencedDocumentMessage, local: boolean) {\n this.runtime.process(message, local);\n }\n\n public processSignal(message: ISignalMessage, local: boolean) {\n this.runtime.processSignal(message, local);\n }\n\n public async request(path: IRequest): Promise<IResponse> {\n return this.runtime.request(path);\n }\n\n public async getAbsoluteUrl(relativeUrl: string): Promise<string | undefined> {\n return this.container.getAbsoluteUrl(relativeUrl);\n }\n\n public getPendingLocalState(): unknown {\n return this.runtime.getPendingLocalState();\n }\n\n /**\n * Determines if the current code details of the context\n * satisfy the incoming constraint code details\n */\n public async satisfies(constraintCodeDetails: IFluidCodeDetails) {\n const comparers: IFluidCodeDetailsComparer[] = [];\n\n const maybeCompareCodeLoader = this.codeLoader;\n if (maybeCompareCodeLoader.IFluidCodeDetailsComparer !== undefined) {\n comparers.push(maybeCompareCodeLoader.IFluidCodeDetailsComparer);\n }\n\n const moduleWithDetails = await this._fluidModuleP;\n const maybeCompareExport: Partial<IProvideFluidCodeDetailsComparer> | undefined =\n moduleWithDetails.module?.fluidExport;\n if (maybeCompareExport?.IFluidCodeDetailsComparer !== undefined) {\n comparers.push(maybeCompareExport.IFluidCodeDetailsComparer);\n }\n\n // if there are not comparers it is not possible to know\n // if the current satisfy the incoming, so return false,\n // as assuming they do not satisfy is safer .e.g we will\n // reload, rather than potentially running with\n // incompatible code\n if (comparers.length === 0) {\n return false;\n }\n\n for (const comparer of comparers) {\n const satisfies = await comparer.satisfies(\n moduleWithDetails.details,\n constraintCodeDetails,\n );\n if (satisfies === false) {\n return false;\n }\n }\n return true;\n }\n\n public notifyAttaching(snapshot: ISnapshotTreeWithBlobContents) {\n this._baseSnapshot = snapshot;\n this.runtime.notifyAttaching?.(snapshot);\n this.runtime.setAttachState(AttachState.Attaching);\n }\n\n // #region private\n\n private async getRuntimeFactory(): Promise<IRuntimeFactory> {\n const fluidExport: FluidObject<IProvideRuntimeFactory> | undefined =\n (await this._fluidModuleP).module?.fluidExport;\n const runtimeFactory = fluidExport?.IRuntimeFactory;\n if (runtimeFactory === undefined) {\n throw new Error(PackageNotFactoryError);\n }\n\n return runtimeFactory;\n }\n\n private async instantiateRuntime(existing: boolean) {\n const runtimeFactory = await this.getRuntimeFactory();\n await ReportIfTooLong(\n this.taggedLogger,\n \"instantiateRuntime\",\n async () => {\n this._runtime = await runtimeFactory.instantiateRuntime(this, existing);\n return {};\n });\n }\n\n private attachListener() {\n this.container.once(\"attached\", () => {\n this.runtime.setAttachState(AttachState.Attached);\n });\n }\n\n private async loadCodeModule(codeDetails: IFluidCodeDetails): Promise<IFluidModuleWithDetails> {\n const loadCodeResult = await PerformanceEvent.timedExecAsync(\n this.taggedLogger,\n { eventName: \"CodeLoad\" },\n async () => this.codeLoader.load(codeDetails),\n );\n\n if (\"module\" in loadCodeResult) {\n const { module, details } = loadCodeResult;\n return {\n module,\n details: details ?? codeDetails,\n };\n } else {\n // If \"module\" is not in the result, we are using a legacy ICodeLoader. Fix the result up with details.\n // Once usage drops to 0 we can remove this compat path.\n this.taggedLogger.sendTelemetryEvent({ eventName: \"LegacyCodeLoader\" });\n return loadCodeResult;\n }\n }\n // #endregion\n}\n"]}
1
+ {"version":3,"file":"containerContext.js","sourceRoot":"","sources":["../src/containerContext.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, LazyPromise, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport {\n\tIAudience,\n\tIContainerContext,\n\tIDeltaManager,\n\tILoader,\n\tIRuntime,\n\tICriticalContainerError,\n\tAttachState,\n\tILoaderOptions,\n\tIRuntimeFactory,\n\tIProvideRuntimeFactory,\n\tIFluidCodeDetails,\n\tIFluidCodeDetailsComparer,\n\tIProvideFluidCodeDetailsComparer,\n\tICodeDetailsLoader,\n\tIFluidModuleWithDetails,\n\tIBatchMessage,\n} from \"@fluidframework/container-definitions\";\nimport { IRequest, IResponse, FluidObject } from \"@fluidframework/core-interfaces\";\nimport { IDocumentStorageService } from \"@fluidframework/driver-definitions\";\nimport { isFluidResolvedUrl } from \"@fluidframework/driver-utils\";\nimport {\n\tIClientConfiguration,\n\tIClientDetails,\n\tIDocumentMessage,\n\tIQuorum,\n\tIQuorumClients,\n\tISequencedDocumentMessage,\n\tISignalMessage,\n\tISnapshotTree,\n\tISummaryTree,\n\tIVersion,\n\tMessageType,\n\tISummaryContent,\n} from \"@fluidframework/protocol-definitions\";\nimport { PerformanceEvent } from \"@fluidframework/telemetry-utils\";\nimport { UsageError } from \"@fluidframework/container-utils\";\nimport { Container } from \"./container\";\n\nconst PackageNotFactoryError = \"Code package does not implement IRuntimeFactory\";\n\n/**\n * Events that {@link ContainerContext} can emit through its lifecycle.\n *\n * \"runtimeInstantiated\" - When an {@link @fluidframework/container-definitions#IRuntime} has been instantiated (by\n * calling instantiateRuntime() on the runtime factory), and this._runtime is set.\n *\n * \"disposed\" - When its dispose() method is called. The {@link ContainerContext} is no longer usable at that point.\n */\ntype ContextLifecycleEvents = \"runtimeInstantiated\" | \"disposed\";\n\nexport class ContainerContext implements IContainerContext {\n\tpublic static async createOrLoad(\n\t\tcontainer: Container,\n\t\tscope: FluidObject,\n\t\tcodeLoader: ICodeDetailsLoader,\n\t\tcodeDetails: IFluidCodeDetails,\n\t\tbaseSnapshot: ISnapshotTree | undefined,\n\t\tdeltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tquorum: IQuorum,\n\t\tloader: ILoader,\n\t\tsubmitFn: (type: MessageType, contents: any, batch: boolean, appData: any) => number,\n\t\tsubmitSummaryFn: (summaryOp: ISummaryContent, referenceSequenceNumber?: number) => number,\n\t\tsubmitBatchFn: (batch: IBatchMessage[], referenceSequenceNumber?: number) => number,\n\t\tsubmitSignalFn: (contents: any) => void,\n\t\tdisposeFn: (error?: ICriticalContainerError) => void,\n\t\tcloseFn: (error?: ICriticalContainerError) => void,\n\t\tversion: string,\n\t\tupdateDirtyContainerState: (dirty: boolean) => void,\n\t\texisting: boolean,\n\t\tpendingLocalState?: unknown,\n\t): Promise<ContainerContext> {\n\t\tconst context = new ContainerContext(\n\t\t\tcontainer,\n\t\t\tscope,\n\t\t\tcodeLoader,\n\t\t\tcodeDetails,\n\t\t\tbaseSnapshot,\n\t\t\tdeltaManager,\n\t\t\tquorum,\n\t\t\tloader,\n\t\t\tsubmitFn,\n\t\t\tsubmitSummaryFn,\n\t\t\tsubmitBatchFn,\n\t\t\tsubmitSignalFn,\n\t\t\tdisposeFn,\n\t\t\tcloseFn,\n\t\t\tversion,\n\t\t\tupdateDirtyContainerState,\n\t\t\texisting,\n\t\t\tpendingLocalState,\n\t\t);\n\t\tawait context.instantiateRuntime(existing);\n\t\treturn context;\n\t}\n\n\tpublic readonly taggedLogger: ITelemetryLogger;\n\tpublic readonly supportedFeatures: ReadonlyMap<string, unknown>;\n\n\tpublic get clientId(): string | undefined {\n\t\treturn this.container.clientId;\n\t}\n\n\t/**\n\t * DISCLAIMER: this id is only for telemetry purposes. Not suitable for any other usages.\n\t */\n\tpublic get id(): string {\n\t\tconst resolvedUrl = this.container.resolvedUrl;\n\t\tif (isFluidResolvedUrl(resolvedUrl)) {\n\t\t\treturn resolvedUrl.id;\n\t\t}\n\t\treturn \"\";\n\t}\n\n\tpublic get clientDetails(): IClientDetails {\n\t\treturn this.container.clientDetails;\n\t}\n\n\tprivate _connected: boolean;\n\t/**\n\t * When true, ops are free to flow\n\t * When false, ops should be kept as pending or rejected\n\t */\n\tpublic get connected(): boolean {\n\t\treturn this._connected;\n\t}\n\n\tpublic get canSummarize(): boolean {\n\t\treturn \"summarize\" in this.runtime;\n\t}\n\n\tpublic get serviceConfiguration(): IClientConfiguration | undefined {\n\t\treturn this.container.serviceConfiguration;\n\t}\n\n\tpublic get audience(): IAudience {\n\t\treturn this.container.audience;\n\t}\n\n\tpublic get options(): ILoaderOptions {\n\t\treturn this.container.options;\n\t}\n\n\tpublic get baseSnapshot() {\n\t\treturn this._baseSnapshot;\n\t}\n\n\tpublic get storage(): IDocumentStorageService {\n\t\treturn this.container.storage;\n\t}\n\n\tprivate _runtime: IRuntime | undefined;\n\tprivate get runtime() {\n\t\tif (this._runtime === undefined) {\n\t\t\tthrow new Error(\"Attempted to access runtime before it was defined\");\n\t\t}\n\t\treturn this._runtime;\n\t}\n\n\tprivate _disposed = false;\n\n\tpublic get disposed() {\n\t\treturn this._disposed;\n\t}\n\n\tpublic get codeDetails() {\n\t\treturn this._codeDetails;\n\t}\n\n\tprivate readonly _quorum: IQuorum;\n\tpublic get quorum(): IQuorumClients {\n\t\treturn this._quorum;\n\t}\n\n\tprivate readonly _fluidModuleP: Promise<IFluidModuleWithDetails>;\n\n\t/**\n\t * {@inheritDoc @fluidframework/container-definitions#IContainerContext.getEntryPoint}\n\t */\n\tpublic async getEntryPoint?(): Promise<FluidObject | undefined> {\n\t\tif (this._disposed) {\n\t\t\tthrow new UsageError(\"The context is already disposed\");\n\t\t}\n\t\tif (this._runtime !== undefined) {\n\t\t\treturn this._runtime?.getEntryPoint?.();\n\t\t}\n\t\treturn new Promise<FluidObject | undefined>((resolve, reject) => {\n\t\t\tconst runtimeInstantiatedHandler = () => {\n\t\t\t\tassert(\n\t\t\t\t\tthis._runtime !== undefined,\n\t\t\t\t\t0x5a3 /* runtimeInstantiated fired but runtime is still undefined */,\n\t\t\t\t);\n\t\t\t\tresolve(this._runtime.getEntryPoint?.());\n\t\t\t\tthis.lifecycleEvents.off(\"disposed\", disposedHandler);\n\t\t\t};\n\t\t\tconst disposedHandler = () => {\n\t\t\t\treject(new Error(\"ContainerContext was disposed\"));\n\t\t\t\tthis.lifecycleEvents.off(\"runtimeInstantiated\", runtimeInstantiatedHandler);\n\t\t\t};\n\t\t\tthis.lifecycleEvents.once(\"runtimeInstantiated\", runtimeInstantiatedHandler);\n\t\t\tthis.lifecycleEvents.once(\"disposed\", disposedHandler);\n\t\t});\n\t}\n\n\t/**\n\t * Emits events about the container context's lifecycle.\n\t * Use it to coordinate things inside the ContainerContext class.\n\t */\n\tprivate readonly lifecycleEvents = new TypedEventEmitter<ContextLifecycleEvents>();\n\n\tconstructor(\n\t\tprivate readonly container: Container,\n\t\tpublic readonly scope: FluidObject,\n\t\tprivate readonly codeLoader: ICodeDetailsLoader,\n\t\tprivate readonly _codeDetails: IFluidCodeDetails,\n\t\tprivate readonly _baseSnapshot: ISnapshotTree | undefined,\n\t\tpublic readonly deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,\n\t\tquorum: IQuorum,\n\t\tpublic readonly loader: ILoader,\n\t\tpublic readonly submitFn: (\n\t\t\ttype: MessageType,\n\t\t\tcontents: any,\n\t\t\tbatch: boolean,\n\t\t\tappData: any,\n\t\t) => number,\n\t\tpublic readonly submitSummaryFn: (\n\t\t\tsummaryOp: ISummaryContent,\n\t\t\treferenceSequenceNumber?: number,\n\t\t) => number,\n\t\t/** @returns clientSequenceNumber of last message in a batch */\n\t\tpublic readonly submitBatchFn: (\n\t\t\tbatch: IBatchMessage[],\n\t\t\treferenceSequenceNumber?: number,\n\t\t) => number,\n\t\tpublic readonly submitSignalFn: (contents: any) => void,\n\t\tpublic readonly disposeFn: (error?: ICriticalContainerError) => void,\n\t\tpublic readonly closeFn: (error?: ICriticalContainerError) => void,\n\t\tpublic readonly version: string,\n\t\tpublic readonly updateDirtyContainerState: (dirty: boolean) => void,\n\t\tpublic readonly existing: boolean,\n\t\tpublic readonly pendingLocalState?: unknown,\n\t) {\n\t\tthis._connected = this.container.connected;\n\t\tthis._quorum = quorum;\n\t\tthis.taggedLogger = container.subLogger;\n\t\tthis._fluidModuleP = new LazyPromise<IFluidModuleWithDetails>(async () =>\n\t\t\tthis.loadCodeModule(_codeDetails),\n\t\t);\n\n\t\tthis.supportedFeatures = new Map([\n\t\t\t/**\n\t\t\t * This version of the loader accepts `referenceSequenceNumber`, provided by the container runtime,\n\t\t\t * as a parameter to the `submitBatchFn` and `submitSummaryFn` functions.\n\t\t\t * This is then used to set the reference sequence numbers of the submitted ops in the DeltaManager.\n\t\t\t */\n\t\t\t[\"referenceSequenceNumbers\", true],\n\t\t]);\n\t\tthis.attachListener();\n\t}\n\n\t/**\n\t * @deprecated Temporary migratory API, to be removed when customers no longer need it.\n\t * When removed, `ContainerContext` should only take an {@link @fluidframework/container-definitions#IQuorumClients}\n\t * rather than an {@link @fluidframework/protocol-definitions#IQuorum}.\n\t * See {@link @fluidframework/container-definitions#IContainerContext} for more details.\n\t */\n\tpublic getSpecifiedCodeDetails(): IFluidCodeDetails | undefined {\n\t\treturn (this._quorum.get(\"code\") ?? this._quorum.get(\"code2\")) as\n\t\t\t| IFluidCodeDetails\n\t\t\t| undefined;\n\t}\n\n\tpublic dispose(error?: Error): void {\n\t\tif (this._disposed) {\n\t\t\treturn;\n\t\t}\n\t\tthis._disposed = true;\n\n\t\tthis.lifecycleEvents.emit(\"disposed\");\n\t\tthis.runtime.dispose(error);\n\t\tthis._quorum.dispose();\n\t\tthis.deltaManager.dispose();\n\t}\n\n\tpublic getLoadedFromVersion(): IVersion | undefined {\n\t\treturn this.container.loadedFromVersion;\n\t}\n\n\tpublic get attachState(): AttachState {\n\t\treturn this.container.attachState;\n\t}\n\n\t/**\n\t * Create a summary. Used when attaching or serializing a detached container.\n\t *\n\t * @param blobRedirectTable - A table passed during the attach process. While detached, blob upload is supported\n\t * using IDs generated locally. After attach, these IDs cannot be used, so this table maps the old local IDs to the\n\t * new storage IDs so requests can be redirected.\n\t */\n\tpublic createSummary(blobRedirectTable?: Map<string, string>): ISummaryTree {\n\t\treturn this.runtime.createSummary(blobRedirectTable);\n\t}\n\n\tpublic setConnectionState(connected: boolean, clientId?: string) {\n\t\tconst runtime = this.runtime;\n\t\tthis._connected = connected;\n\t\truntime.setConnectionState(connected, clientId);\n\t}\n\n\tpublic process(message: ISequencedDocumentMessage, local: boolean) {\n\t\tthis.runtime.process(message, local);\n\t}\n\n\tpublic processSignal(message: ISignalMessage, local: boolean) {\n\t\tthis.runtime.processSignal(message, local);\n\t}\n\n\tpublic async request(path: IRequest): Promise<IResponse> {\n\t\treturn this.runtime.request(path);\n\t}\n\n\tpublic async getAbsoluteUrl(relativeUrl: string): Promise<string | undefined> {\n\t\treturn this.container.getAbsoluteUrl(relativeUrl);\n\t}\n\n\tpublic getPendingLocalState(): unknown {\n\t\treturn this.runtime.getPendingLocalState();\n\t}\n\n\t/**\n\t * Determines if the current code details of the context\n\t * satisfy the incoming constraint code details\n\t */\n\tpublic async satisfies(constraintCodeDetails: IFluidCodeDetails) {\n\t\tconst comparers: IFluidCodeDetailsComparer[] = [];\n\n\t\tconst maybeCompareCodeLoader = this.codeLoader;\n\t\tif (maybeCompareCodeLoader.IFluidCodeDetailsComparer !== undefined) {\n\t\t\tcomparers.push(maybeCompareCodeLoader.IFluidCodeDetailsComparer);\n\t\t}\n\n\t\tconst moduleWithDetails = await this._fluidModuleP;\n\t\tconst maybeCompareExport: Partial<IProvideFluidCodeDetailsComparer> | undefined =\n\t\t\tmoduleWithDetails.module?.fluidExport;\n\t\tif (maybeCompareExport?.IFluidCodeDetailsComparer !== undefined) {\n\t\t\tcomparers.push(maybeCompareExport.IFluidCodeDetailsComparer);\n\t\t}\n\n\t\t// if there are not comparers it is not possible to know\n\t\t// if the current satisfy the incoming, so return false,\n\t\t// as assuming they do not satisfy is safer .e.g we will\n\t\t// reload, rather than potentially running with\n\t\t// incompatible code\n\t\tif (comparers.length === 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (const comparer of comparers) {\n\t\t\tconst satisfies = await comparer.satisfies(\n\t\t\t\tmoduleWithDetails.details,\n\t\t\t\tconstraintCodeDetails,\n\t\t\t);\n\t\t\tif (satisfies === false) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\tpublic async notifyOpReplay(message: ISequencedDocumentMessage): Promise<void> {\n\t\treturn this.runtime.notifyOpReplay?.(message);\n\t}\n\n\t// #region private\n\n\tprivate async getRuntimeFactory(): Promise<IRuntimeFactory> {\n\t\tconst fluidExport: FluidObject<IProvideRuntimeFactory> | undefined = (\n\t\t\tawait this._fluidModuleP\n\t\t).module?.fluidExport;\n\t\tconst runtimeFactory = fluidExport?.IRuntimeFactory;\n\t\tif (runtimeFactory === undefined) {\n\t\t\tthrow new Error(PackageNotFactoryError);\n\t\t}\n\n\t\treturn runtimeFactory;\n\t}\n\n\tprivate async instantiateRuntime(existing: boolean) {\n\t\tconst runtimeFactory = await this.getRuntimeFactory();\n\t\tthis._runtime = await PerformanceEvent.timedExecAsync(\n\t\t\tthis.taggedLogger,\n\t\t\t{ eventName: \"InstantiateRuntime\" },\n\t\t\tasync () => runtimeFactory.instantiateRuntime(this, existing),\n\t\t);\n\t\tthis.lifecycleEvents.emit(\"runtimeInstantiated\");\n\t}\n\n\tprivate attachListener() {\n\t\tthis.container.once(\"attaching\", () => {\n\t\t\tthis.runtime.setAttachState(AttachState.Attaching);\n\t\t});\n\t\tthis.container.once(\"attached\", () => {\n\t\t\tthis.runtime.setAttachState(AttachState.Attached);\n\t\t});\n\t}\n\n\tprivate async loadCodeModule(codeDetails: IFluidCodeDetails): Promise<IFluidModuleWithDetails> {\n\t\tconst loadCodeResult = await PerformanceEvent.timedExecAsync(\n\t\t\tthis.taggedLogger,\n\t\t\t{ eventName: \"CodeLoad\" },\n\t\t\tasync () => this.codeLoader.load(codeDetails),\n\t\t);\n\n\t\tif (\"module\" in loadCodeResult) {\n\t\t\tconst { module, details } = loadCodeResult;\n\t\t\treturn {\n\t\t\t\tmodule,\n\t\t\t\tdetails: details ?? codeDetails,\n\t\t\t};\n\t\t} else {\n\t\t\t// If \"module\" is not in the result, we are using a legacy ICodeLoader. Fix the result up with details.\n\t\t\t// Once usage drops to 0 we can remove this compat path.\n\t\t\tthis.taggedLogger.sendTelemetryEvent({ eventName: \"LegacyCodeLoader\" });\n\t\t\treturn loadCodeResult;\n\t\t}\n\t}\n\t// #endregion\n}\n"]}
@@ -7,16 +7,47 @@ import { ISnapshotTreeWithBlobContents } from "@fluidframework/container-definit
7
7
  import { FetchSource, IDocumentService, IDocumentStorageService, IDocumentStorageServicePolicies, ISummaryContext } from "@fluidframework/driver-definitions";
8
8
  import { ICreateBlobResponse, ISnapshotTree, ISummaryHandle, ISummaryTree, IVersion } from "@fluidframework/protocol-definitions";
9
9
  import { IDetachedBlobStorage } from "./loader";
10
+ /**
11
+ * Stringified blobs from a summary/snapshot tree.
12
+ * @deprecated this is an internal interface and will not longer be exported in future versions
13
+ * @internal
14
+ */
15
+ export interface ISerializableBlobContents {
16
+ [id: string]: string;
17
+ }
10
18
  /**
11
19
  * This class wraps the actual storage and make sure no wrong apis are called according to
12
20
  * container attach state.
13
21
  */
14
22
  export declare class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {
15
23
  private readonly logger;
16
- private readonly captureProtocolSummary?;
24
+ /**
25
+ * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
26
+ */
17
27
  private readonly blobContents;
28
+ private readonly addProtocolSummaryIfMissing;
18
29
  private _storageService;
19
- constructor(detachedBlobStorage: IDetachedBlobStorage | undefined, logger: ITelemetryLogger, captureProtocolSummary?: (() => ISummaryTree) | undefined);
30
+ private _summarizeProtocolTree;
31
+ /**
32
+ * Whether the adapter will enforce sending combined summary trees.
33
+ */
34
+ get summarizeProtocolTree(): boolean;
35
+ /**
36
+ * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then
37
+ * after connecting to a real service augments it with retry and combined summary tree enforcement.
38
+ * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service
39
+ * @param logger - Telemetry logger
40
+ * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to
41
+ * upload, and fix it up with a protocol tree if needed
42
+ * @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
43
+ */
44
+ constructor(detachedBlobStorage: IDetachedBlobStorage | undefined, logger: ITelemetryLogger,
45
+ /**
46
+ * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
47
+ */
48
+ blobContents: {
49
+ [id: string]: ArrayBufferLike | string;
50
+ }, addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree, forceEnableSummarizeProtocolTree: boolean | undefined);
20
51
  disposed: boolean;
21
52
  dispose(error?: Error): void;
22
53
  connectToService(service: IDocumentService): Promise<void>;
@@ -31,4 +62,12 @@ export declare class ContainerStorageAdapter implements IDocumentStorageService,
31
62
  downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree>;
32
63
  createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse>;
33
64
  }
65
+ /**
66
+ * Get blob contents of a snapshot tree from storage (or, ideally, cache)
67
+ */
68
+ export declare function getBlobContentsFromTree(snapshot: ISnapshotTree, storage: IDocumentStorageService): Promise<ISerializableBlobContents>;
69
+ /**
70
+ * Extract blob contents from a snapshot tree with blob contents
71
+ */
72
+ export declare function getBlobContentsFromTreeWithBlobContents(snapshot: ISnapshotTreeWithBlobContents): ISerializableBlobContents;
34
73
  //# sourceMappingURL=containerStorageAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEnF,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EACH,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EAClB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACH,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,QAAQ,EACX,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIhD;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,uBAAuB,EAAE,WAAW;IAM5E,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;IAN5C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA0C;IACvE,OAAO,CAAC,eAAe,CAAiD;gBAGpE,mBAAmB,EAAE,oBAAoB,GAAG,SAAS,EACpC,MAAM,EAAE,gBAAgB,EACxB,sBAAsB,CAAC,SAAQ,YAAY,aAAA;IAKhE,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAKf,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhE,mCAAmC,CAAC,YAAY,EAAE,6BAA6B;IAItF,OAAO,CAAC,eAAe;IASvB,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAOjE;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAIzF,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAQ9C,WAAW,CACpB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,GAC1B,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIT,wBAAwB,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAI1F,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAG/E"}
1
+ {"version":3,"file":"containerStorageAdapter.d.ts","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEnF,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EACN,WAAW,EACX,gBAAgB,EAChB,uBAAuB,EACvB,+BAA+B,EAC/B,eAAe,EACf,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EACN,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIhD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,uBAAuB,EAAE,WAAW;IAsBlF,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,2BAA2B;IA1B7C,OAAO,CAAC,eAAe,CAAiD;IAExE,OAAO,CAAC,sBAAsB,CAAsB;IACpD;;OAEG;IACH,IAAW,qBAAqB,YAE/B;IAED;;;;;;;;OAQG;gBAEF,mBAAmB,EAAE,oBAAoB,GAAG,SAAS,EACpC,MAAM,EAAE,gBAAgB;IACzC;;OAEG;IACc,YAAY,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,MAAM,CAAA;KAAO,EAC7D,2BAA2B,EAAE,CAAC,WAAW,EAAE,YAAY,KAAK,YAAY,EACzF,gCAAgC,EAAE,OAAO,GAAG,SAAS;IAMtD,QAAQ,EAAE,OAAO,CAAS;IAC1B,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI;IAKf,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BhE,mCAAmC,CAAC,YAAY,EAAE,6BAA6B;IAItF,OAAO,CAAC,eAAe;IASvB,IAAW,QAAQ,IAAI,+BAA+B,GAAG,SAAS,CAOjE;IAED,IAAW,aAAa,IAAI,MAAM,CAEjC;IAEY,eAAe,CAC3B,OAAO,CAAC,EAAE,QAAQ,EAClB,YAAY,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAInB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAY9C,WAAW,CACvB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,WAAW,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC;IAIT,wBAAwB,CACpC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAIL,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAI9D,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAG5E;AA6DD;;GAEG;AACH,wBAAsB,uBAAuB,CAC5C,QAAQ,EAAE,aAAa,EACvB,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CAIpC;AAsBD;;GAEG;AACH,wBAAgB,uCAAuC,CACtD,QAAQ,EAAE,6BAA6B,GACrC,yBAAyB,CAI3B"}
@@ -2,7 +2,7 @@
2
2
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
3
  * Licensed under the MIT License.
4
4
  */
5
- import { assert } from "@fluidframework/common-utils";
5
+ import { assert, bufferToString, stringToBuffer } from "@fluidframework/common-utils";
6
6
  import { UsageError } from "@fluidframework/driver-utils";
7
7
  import { ProtocolTreeStorageService } from "./protocolTreeDocumentStorageService";
8
8
  import { RetriableDocumentStorageService } from "./retriableDocumentStorageService";
@@ -11,12 +11,32 @@ import { RetriableDocumentStorageService } from "./retriableDocumentStorageServi
11
11
  * container attach state.
12
12
  */
13
13
  export class ContainerStorageAdapter {
14
- constructor(detachedBlobStorage, logger, captureProtocolSummary) {
14
+ /**
15
+ * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then
16
+ * after connecting to a real service augments it with retry and combined summary tree enforcement.
17
+ * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service
18
+ * @param logger - Telemetry logger
19
+ * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to
20
+ * upload, and fix it up with a protocol tree if needed
21
+ * @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy
22
+ */
23
+ constructor(detachedBlobStorage, logger,
24
+ /**
25
+ * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
26
+ */
27
+ blobContents = {}, addProtocolSummaryIfMissing, forceEnableSummarizeProtocolTree) {
15
28
  this.logger = logger;
16
- this.captureProtocolSummary = captureProtocolSummary;
17
- this.blobContents = {};
29
+ this.blobContents = blobContents;
30
+ this.addProtocolSummaryIfMissing = addProtocolSummaryIfMissing;
18
31
  this.disposed = false;
19
32
  this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);
33
+ this._summarizeProtocolTree = forceEnableSummarizeProtocolTree;
34
+ }
35
+ /**
36
+ * Whether the adapter will enforce sending combined summary trees.
37
+ */
38
+ get summarizeProtocolTree() {
39
+ return this._summarizeProtocolTree === true;
20
40
  }
21
41
  dispose(error) {
22
42
  var _a, _b;
@@ -24,20 +44,20 @@ export class ContainerStorageAdapter {
24
44
  this.disposed = true;
25
45
  }
26
46
  async connectToService(service) {
27
- var _a, _b;
47
+ var _a, _b, _c, _d;
28
48
  if (!(this._storageService instanceof BlobOnlyStorage)) {
29
49
  return;
30
50
  }
31
51
  const storageService = await service.connectToStorage();
32
- const retriableStorage = this._storageService =
33
- new RetriableDocumentStorageService(storageService, this.logger);
34
- if (this.captureProtocolSummary !== undefined) {
52
+ const retriableStorage = (this._storageService = new RetriableDocumentStorageService(storageService, this.logger));
53
+ this._summarizeProtocolTree =
54
+ (_a = this._summarizeProtocolTree) !== null && _a !== void 0 ? _a : (_b = service.policies) === null || _b === void 0 ? void 0 : _b.summarizeProtocolTree;
55
+ if (this.summarizeProtocolTree) {
35
56
  this.logger.sendTelemetryEvent({ eventName: "summarizeProtocolTreeEnabled" });
36
- this._storageService =
37
- new ProtocolTreeStorageService(retriableStorage, this.captureProtocolSummary);
57
+ this._storageService = new ProtocolTreeStorageService(retriableStorage, this.addProtocolSummaryIfMissing);
38
58
  }
39
59
  // ensure we did not lose that policy in the process of wrapping
40
- assert(((_a = storageService.policies) === null || _a === void 0 ? void 0 : _a.minBlobSize) === ((_b = this._storageService.policies) === null || _b === void 0 ? void 0 : _b.minBlobSize), 0x0e0 /* "lost minBlobSize policy" */);
60
+ assert(((_c = storageService.policies) === null || _c === void 0 ? void 0 : _c.minBlobSize) === ((_d = this._storageService.policies) === null || _d === void 0 ? void 0 : _d.minBlobSize), 0x0e0 /* "lost minBlobSize policy" */);
41
61
  }
42
62
  loadSnapshotForRehydratingContainer(snapshotTree) {
43
63
  this.getBlobContents(snapshotTree);
@@ -66,9 +86,13 @@ export class ContainerStorageAdapter {
66
86
  return this._storageService.getSnapshotTree(version, scenarioName);
67
87
  }
68
88
  async readBlob(id) {
69
- const blob = this.blobContents[id];
70
- if (blob !== undefined) {
71
- return blob;
89
+ const maybeBlob = this.blobContents[id];
90
+ if (maybeBlob !== undefined) {
91
+ if (typeof maybeBlob === "string") {
92
+ const blob = stringToBuffer(maybeBlob, "utf8");
93
+ return blob;
94
+ }
95
+ return maybeBlob;
72
96
  }
73
97
  return this._storageService.readBlob(id);
74
98
  }
@@ -131,4 +155,52 @@ class BlobOnlyStorage {
131
155
  }
132
156
  }
133
157
  }
158
+ // runtime will write a tree to the summary containing only "attachment" type entries
159
+ // which reference attachment blobs by ID. However, some drivers do not support this type
160
+ // and will convert them to "blob" type entries. We want to avoid saving these to reduce
161
+ // the size of stashed change blobs.
162
+ const blobsTreeName = ".blobs";
163
+ /**
164
+ * Get blob contents of a snapshot tree from storage (or, ideally, cache)
165
+ */
166
+ export async function getBlobContentsFromTree(snapshot, storage) {
167
+ const blobs = {};
168
+ await getBlobContentsFromTreeCore(snapshot, blobs, storage);
169
+ return blobs;
170
+ }
171
+ async function getBlobContentsFromTreeCore(tree, blobs, storage, root = true) {
172
+ const treePs = [];
173
+ for (const [key, subTree] of Object.entries(tree.trees)) {
174
+ if (!root || key !== blobsTreeName) {
175
+ treePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));
176
+ }
177
+ }
178
+ for (const id of Object.values(tree.blobs)) {
179
+ const blob = await storage.readBlob(id);
180
+ // ArrayBufferLike will not survive JSON.stringify()
181
+ blobs[id] = bufferToString(blob, "utf8");
182
+ }
183
+ return Promise.all(treePs);
184
+ }
185
+ /**
186
+ * Extract blob contents from a snapshot tree with blob contents
187
+ */
188
+ export function getBlobContentsFromTreeWithBlobContents(snapshot) {
189
+ const blobs = {};
190
+ getBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);
191
+ return blobs;
192
+ }
193
+ function getBlobContentsFromTreeWithBlobContentsCore(tree, blobs, root = true) {
194
+ for (const [key, subTree] of Object.entries(tree.trees)) {
195
+ if (!root || key !== blobsTreeName) {
196
+ getBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);
197
+ }
198
+ }
199
+ for (const id of Object.values(tree.blobs)) {
200
+ const blob = tree.blobsContents[id];
201
+ assert(blob !== undefined, 0x2ec /* "Blob must be present in blobsContents" */);
202
+ // ArrayBufferLike will not survive JSON.stringify()
203
+ blobs[id] = bufferToString(blob, "utf8");
204
+ }
205
+ }
134
206
  //# sourceMappingURL=containerStorageAdapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert } from \"@fluidframework/common-utils\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n FetchSource,\n IDocumentService,\n IDocumentStorageService,\n IDocumentStorageServicePolicies,\n ISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport {\n ICreateBlobResponse,\n ISnapshotTree,\n ISummaryHandle,\n ISummaryTree,\n IVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDetachedBlobStorage } from \"./loader\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService\";\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {\n private readonly blobContents: { [id: string]: ArrayBufferLike; } = {};\n private _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n constructor(\n detachedBlobStorage: IDetachedBlobStorage | undefined,\n private readonly logger: ITelemetryLogger,\n private readonly captureProtocolSummary?: () => ISummaryTree,\n ) {\n this._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n }\n\n disposed: boolean = false;\n dispose(error?: Error): void {\n this._storageService?.dispose?.(error);\n this.disposed = true;\n }\n\n public async connectToService(service: IDocumentService): Promise<void> {\n if (!(this._storageService instanceof BlobOnlyStorage)) {\n return;\n }\n\n const storageService = await service.connectToStorage();\n const retriableStorage = this._storageService =\n new RetriableDocumentStorageService(\n storageService,\n this.logger);\n\n if (this.captureProtocolSummary !== undefined) {\n this.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n this._storageService =\n new ProtocolTreeStorageService(retriableStorage, this.captureProtocolSummary);\n }\n\n // ensure we did not lose that policy in the process of wrapping\n assert(storageService.policies?.minBlobSize === this._storageService.policies?.minBlobSize,\n 0x0e0 /* \"lost minBlobSize policy\" */);\n }\n\n public loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {\n this.getBlobContents(snapshotTree);\n }\n\n private getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {\n for (const [id, value] of Object.entries(snapshotTree.blobsContents)) {\n this.blobContents[id] = value;\n }\n for (const [_, tree] of Object.entries(snapshotTree.trees)) {\n this.getBlobContents(tree);\n }\n }\n\n public get policies(): IDocumentStorageServicePolicies | undefined {\n // back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n // and storage is always present in >=0.41.\n try {\n return this._storageService.policies;\n } catch (e) {}\n return undefined;\n }\n\n public get repositoryUrl(): string {\n return this._storageService.repositoryUrl;\n }\n\n public async getSnapshotTree(version?: IVersion, scenarioName?: string): Promise<ISnapshotTree | null> {\n return this._storageService.getSnapshotTree(version, scenarioName);\n }\n\n public async readBlob(id: string): Promise<ArrayBufferLike> {\n const blob = this.blobContents[id];\n if (blob !== undefined) {\n return blob;\n }\n return this._storageService.readBlob(id);\n }\n\n public async getVersions(\n versionId: string | null,\n count: number,\n scenarioName?: string,\n fetchSource?: FetchSource,\n ): Promise<IVersion[]> {\n return this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n }\n\n public async uploadSummaryWithContext(summary: ISummaryTree, context: ISummaryContext): Promise<string> {\n return this._storageService.uploadSummaryWithContext(summary, context);\n }\n\n public async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n return this._storageService.downloadSummary(handle);\n }\n\n public async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n return this._storageService.createBlob(file);\n }\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n constructor(\n private readonly detachedStorage: IDetachedBlobStorage | undefined,\n private readonly logger: ITelemetryLogger,\n ) { }\n\n public async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n return this.verifyStorage().createBlob(content);\n }\n\n public async readBlob(blobId: string): Promise<ArrayBufferLike> {\n return this.verifyStorage().readBlob(blobId);\n }\n\n private verifyStorage(): IDetachedBlobStorage {\n if (this.detachedStorage === undefined) {\n throw new UsageError(\"Real storage calls not allowed in Unattached container\");\n }\n return this.detachedStorage;\n }\n\n public get policies(): IDocumentStorageServicePolicies | undefined {\n return this.notCalled();\n }\n\n public get repositoryUrl(): string {\n return this.notCalled();\n }\n\n /* eslint-disable @typescript-eslint/unbound-method */\n public getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n public getVersions: () => Promise<IVersion[]> = this.notCalled;\n public write: () => Promise<IVersion> = this.notCalled;\n public uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n public downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n /* eslint-enable @typescript-eslint/unbound-method */\n\n private notCalled(): never {\n this.verifyStorage();\n try {\n // some browsers may not populate stack unless exception is thrown\n throw new Error(\"BlobOnlyStorage not implemented method used\");\n } catch (err) {\n this.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, err);\n throw err;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"containerStorageAdapter.js","sourceRoot":"","sources":["../src/containerStorageAdapter.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IDisposable, ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, bufferToString, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\nimport {\n\tFetchSource,\n\tIDocumentService,\n\tIDocumentStorageService,\n\tIDocumentStorageServicePolicies,\n\tISummaryContext,\n} from \"@fluidframework/driver-definitions\";\nimport { UsageError } from \"@fluidframework/driver-utils\";\nimport {\n\tICreateBlobResponse,\n\tISnapshotTree,\n\tISummaryHandle,\n\tISummaryTree,\n\tIVersion,\n} from \"@fluidframework/protocol-definitions\";\nimport { IDetachedBlobStorage } from \"./loader\";\nimport { ProtocolTreeStorageService } from \"./protocolTreeDocumentStorageService\";\nimport { RetriableDocumentStorageService } from \"./retriableDocumentStorageService\";\n\n/**\n * Stringified blobs from a summary/snapshot tree.\n * @deprecated this is an internal interface and will not longer be exported in future versions\n * @internal\n */\nexport interface ISerializableBlobContents {\n\t[id: string]: string;\n}\n\n/**\n * This class wraps the actual storage and make sure no wrong apis are called according to\n * container attach state.\n */\nexport class ContainerStorageAdapter implements IDocumentStorageService, IDisposable {\n\tprivate _storageService: IDocumentStorageService & Partial<IDisposable>;\n\n\tprivate _summarizeProtocolTree: boolean | undefined;\n\t/**\n\t * Whether the adapter will enforce sending combined summary trees.\n\t */\n\tpublic get summarizeProtocolTree() {\n\t\treturn this._summarizeProtocolTree === true;\n\t}\n\n\t/**\n\t * An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then\n\t * after connecting to a real service augments it with retry and combined summary tree enforcement.\n\t * @param detachedBlobStorage - The detached blob storage to use up until we connect to a real service\n\t * @param logger - Telemetry logger\n\t * @param addProtocolSummaryIfMissing - a callback to permit the container to inspect the summary we're about to\n\t * upload, and fix it up with a protocol tree if needed\n\t * @param forceEnableSummarizeProtocolTree - Enforce uploading a protocol summary regardless of the service's policy\n\t */\n\tpublic constructor(\n\t\tdetachedBlobStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t\t/**\n\t\t * ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot\n\t\t */\n\t\tprivate readonly blobContents: { [id: string]: ArrayBufferLike | string } = {},\n\t\tprivate readonly addProtocolSummaryIfMissing: (summaryTree: ISummaryTree) => ISummaryTree,\n\t\tforceEnableSummarizeProtocolTree: boolean | undefined,\n\t) {\n\t\tthis._storageService = new BlobOnlyStorage(detachedBlobStorage, logger);\n\t\tthis._summarizeProtocolTree = forceEnableSummarizeProtocolTree;\n\t}\n\n\tdisposed: boolean = false;\n\tdispose(error?: Error): void {\n\t\tthis._storageService?.dispose?.(error);\n\t\tthis.disposed = true;\n\t}\n\n\tpublic async connectToService(service: IDocumentService): Promise<void> {\n\t\tif (!(this._storageService instanceof BlobOnlyStorage)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst storageService = await service.connectToStorage();\n\t\tconst retriableStorage = (this._storageService = new RetriableDocumentStorageService(\n\t\t\tstorageService,\n\t\t\tthis.logger,\n\t\t));\n\n\t\tthis._summarizeProtocolTree =\n\t\t\tthis._summarizeProtocolTree ?? service.policies?.summarizeProtocolTree;\n\t\tif (this.summarizeProtocolTree) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"summarizeProtocolTreeEnabled\" });\n\t\t\tthis._storageService = new ProtocolTreeStorageService(\n\t\t\t\tretriableStorage,\n\t\t\t\tthis.addProtocolSummaryIfMissing,\n\t\t\t);\n\t\t}\n\n\t\t// ensure we did not lose that policy in the process of wrapping\n\t\tassert(\n\t\t\tstorageService.policies?.minBlobSize === this._storageService.policies?.minBlobSize,\n\t\t\t0x0e0 /* \"lost minBlobSize policy\" */,\n\t\t);\n\t}\n\n\tpublic loadSnapshotForRehydratingContainer(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tthis.getBlobContents(snapshotTree);\n\t}\n\n\tprivate getBlobContents(snapshotTree: ISnapshotTreeWithBlobContents) {\n\t\tfor (const [id, value] of Object.entries(snapshotTree.blobsContents)) {\n\t\t\tthis.blobContents[id] = value;\n\t\t}\n\t\tfor (const [_, tree] of Object.entries(snapshotTree.trees)) {\n\t\t\tthis.getBlobContents(tree);\n\t\t}\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\t// back-compat 0.40 containerRuntime requests policies even in detached container if storage is present\n\t\t// and storage is always present in >=0.41.\n\t\ttry {\n\t\t\treturn this._storageService.policies;\n\t\t} catch (e) {}\n\t\treturn undefined;\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this._storageService.repositoryUrl;\n\t}\n\n\tpublic async getSnapshotTree(\n\t\tversion?: IVersion,\n\t\tscenarioName?: string,\n\t): Promise<ISnapshotTree | null> {\n\t\treturn this._storageService.getSnapshotTree(version, scenarioName);\n\t}\n\n\tpublic async readBlob(id: string): Promise<ArrayBufferLike> {\n\t\tconst maybeBlob = this.blobContents[id];\n\t\tif (maybeBlob !== undefined) {\n\t\t\tif (typeof maybeBlob === \"string\") {\n\t\t\t\tconst blob = stringToBuffer(maybeBlob, \"utf8\");\n\t\t\t\treturn blob;\n\t\t\t}\n\t\t\treturn maybeBlob;\n\t\t}\n\t\treturn this._storageService.readBlob(id);\n\t}\n\n\tpublic async getVersions(\n\t\tversionId: string | null,\n\t\tcount: number,\n\t\tscenarioName?: string,\n\t\tfetchSource?: FetchSource,\n\t): Promise<IVersion[]> {\n\t\treturn this._storageService.getVersions(versionId, count, scenarioName, fetchSource);\n\t}\n\n\tpublic async uploadSummaryWithContext(\n\t\tsummary: ISummaryTree,\n\t\tcontext: ISummaryContext,\n\t): Promise<string> {\n\t\treturn this._storageService.uploadSummaryWithContext(summary, context);\n\t}\n\n\tpublic async downloadSummary(handle: ISummaryHandle): Promise<ISummaryTree> {\n\t\treturn this._storageService.downloadSummary(handle);\n\t}\n\n\tpublic async createBlob(file: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this._storageService.createBlob(file);\n\t}\n}\n\n/**\n * Storage which only supports createBlob() and readBlob(). This is used with IDetachedBlobStorage to support\n * blobs in detached containers.\n */\nclass BlobOnlyStorage implements IDocumentStorageService {\n\tconstructor(\n\t\tprivate readonly detachedStorage: IDetachedBlobStorage | undefined,\n\t\tprivate readonly logger: ITelemetryLogger,\n\t) {}\n\n\tpublic async createBlob(content: ArrayBufferLike): Promise<ICreateBlobResponse> {\n\t\treturn this.verifyStorage().createBlob(content);\n\t}\n\n\tpublic async readBlob(blobId: string): Promise<ArrayBufferLike> {\n\t\treturn this.verifyStorage().readBlob(blobId);\n\t}\n\n\tprivate verifyStorage(): IDetachedBlobStorage {\n\t\tif (this.detachedStorage === undefined) {\n\t\t\tthrow new UsageError(\"Real storage calls not allowed in Unattached container\");\n\t\t}\n\t\treturn this.detachedStorage;\n\t}\n\n\tpublic get policies(): IDocumentStorageServicePolicies | undefined {\n\t\treturn this.notCalled();\n\t}\n\n\tpublic get repositoryUrl(): string {\n\t\treturn this.notCalled();\n\t}\n\n\t/* eslint-disable @typescript-eslint/unbound-method */\n\tpublic getSnapshotTree: () => Promise<ISnapshotTree | null> = this.notCalled;\n\tpublic getVersions: () => Promise<IVersion[]> = this.notCalled;\n\tpublic write: () => Promise<IVersion> = this.notCalled;\n\tpublic uploadSummaryWithContext: () => Promise<string> = this.notCalled;\n\tpublic downloadSummary: () => Promise<ISummaryTree> = this.notCalled;\n\t/* eslint-enable @typescript-eslint/unbound-method */\n\n\tprivate notCalled(): never {\n\t\tthis.verifyStorage();\n\t\ttry {\n\t\t\t// some browsers may not populate stack unless exception is thrown\n\t\t\tthrow new Error(\"BlobOnlyStorage not implemented method used\");\n\t\t} catch (err) {\n\t\t\tthis.logger.sendTelemetryEvent({ eventName: \"BlobOnlyStorageWrongCall\" }, err);\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n// runtime will write a tree to the summary containing only \"attachment\" type entries\n// which reference attachment blobs by ID. However, some drivers do not support this type\n// and will convert them to \"blob\" type entries. We want to avoid saving these to reduce\n// the size of stashed change blobs.\nconst blobsTreeName = \".blobs\";\n\n/**\n * Get blob contents of a snapshot tree from storage (or, ideally, cache)\n */\nexport async function getBlobContentsFromTree(\n\tsnapshot: ISnapshotTree,\n\tstorage: IDocumentStorageService,\n): Promise<ISerializableBlobContents> {\n\tconst blobs = {};\n\tawait getBlobContentsFromTreeCore(snapshot, blobs, storage);\n\treturn blobs;\n}\n\nasync function getBlobContentsFromTreeCore(\n\ttree: ISnapshotTree,\n\tblobs: ISerializableBlobContents,\n\tstorage: IDocumentStorageService,\n\troot = true,\n) {\n\tconst treePs: Promise<any>[] = [];\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (!root || key !== blobsTreeName) {\n\t\t\ttreePs.push(getBlobContentsFromTreeCore(subTree, blobs, storage, false));\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = await storage.readBlob(id);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n\treturn Promise.all(treePs);\n}\n\n/**\n * Extract blob contents from a snapshot tree with blob contents\n */\nexport function getBlobContentsFromTreeWithBlobContents(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISerializableBlobContents {\n\tconst blobs = {};\n\tgetBlobContentsFromTreeWithBlobContentsCore(snapshot, blobs);\n\treturn blobs;\n}\n\nfunction getBlobContentsFromTreeWithBlobContentsCore(\n\ttree: ISnapshotTreeWithBlobContents,\n\tblobs: ISerializableBlobContents,\n\troot = true,\n) {\n\tfor (const [key, subTree] of Object.entries(tree.trees)) {\n\t\tif (!root || key !== blobsTreeName) {\n\t\t\tgetBlobContentsFromTreeWithBlobContentsCore(subTree, blobs, false);\n\t\t}\n\t}\n\tfor (const id of Object.values(tree.blobs)) {\n\t\tconst blob = tree.blobsContents[id];\n\t\tassert(blob !== undefined, 0x2ec /* \"Blob must be present in blobsContents\" */);\n\t\t// ArrayBufferLike will not survive JSON.stringify()\n\t\tblobs[id] = bufferToString(blob, \"utf8\");\n\t}\n}\n"]}