@fluidframework/container-loader 2.63.0-359962 → 2.70.0-360374
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.
- package/CHANGELOG.md +4 -0
- package/api-report/container-loader.legacy.alpha.api.md +28 -0
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +10 -6
- package/dist/container.js.map +1 -1
- package/dist/containerStorageAdapter.d.ts +6 -12
- package/dist/containerStorageAdapter.d.ts.map +1 -1
- package/dist/containerStorageAdapter.js +8 -13
- package/dist/containerStorageAdapter.js.map +1 -1
- package/dist/createAndLoadContainerUtils.d.ts +13 -0
- package/dist/createAndLoadContainerUtils.d.ts.map +1 -1
- package/dist/createAndLoadContainerUtils.js +117 -1
- package/dist/createAndLoadContainerUtils.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/legacyAlpha.d.ts +6 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/serializedStateManager.d.ts +2 -2
- package/dist/serializedStateManager.d.ts.map +1 -1
- package/dist/serializedStateManager.js +2 -1
- package/dist/serializedStateManager.js.map +1 -1
- package/dist/summarizerResultTypes.d.ts +96 -0
- package/dist/summarizerResultTypes.d.ts.map +1 -0
- package/dist/summarizerResultTypes.js +9 -0
- package/dist/summarizerResultTypes.js.map +1 -0
- package/dist/utils.d.ts +1 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +12 -11
- package/dist/utils.js.map +1 -1
- package/lib/container.d.ts.map +1 -1
- package/lib/container.js +11 -7
- package/lib/container.js.map +1 -1
- package/lib/containerStorageAdapter.d.ts +6 -12
- package/lib/containerStorageAdapter.d.ts.map +1 -1
- package/lib/containerStorageAdapter.js +9 -14
- package/lib/containerStorageAdapter.js.map +1 -1
- package/lib/createAndLoadContainerUtils.d.ts +13 -0
- package/lib/createAndLoadContainerUtils.d.ts.map +1 -1
- package/lib/createAndLoadContainerUtils.js +115 -0
- package/lib/createAndLoadContainerUtils.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacyAlpha.d.ts +6 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/serializedStateManager.d.ts +2 -2
- package/lib/serializedStateManager.d.ts.map +1 -1
- package/lib/serializedStateManager.js +2 -1
- package/lib/serializedStateManager.js.map +1 -1
- package/lib/summarizerResultTypes.d.ts +96 -0
- package/lib/summarizerResultTypes.d.ts.map +1 -0
- package/lib/summarizerResultTypes.js +6 -0
- package/lib/summarizerResultTypes.js.map +1 -0
- package/lib/utils.d.ts +1 -2
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +12 -11
- package/lib/utils.js.map +1 -1
- package/package.json +11 -11
- package/src/container.ts +13 -11
- package/src/containerStorageAdapter.ts +9 -12
- package/src/createAndLoadContainerUtils.ts +174 -0
- package/src/index.ts +7 -0
- package/src/packageVersion.ts +1 -1
- package/src/serializedStateManager.ts +6 -3
- package/src/summarizerResultTypes.ts +115 -0
- package/src/utils.ts +15 -14
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { bufferToString
|
|
6
|
+
import { bufferToString } from "@fluid-internal/client-utils";
|
|
7
7
|
import type {
|
|
8
8
|
ISnapshotTreeWithBlobContents,
|
|
9
9
|
IContainerStorageService,
|
|
@@ -71,6 +71,11 @@ export class ContainerStorageAdapter
|
|
|
71
71
|
return this._loadedGroupIdSnapshots;
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* ArrayBufferLikes containing blobs from a snapshot
|
|
76
|
+
*/
|
|
77
|
+
private readonly blobContents: { [id: string]: ArrayBufferLike } = {};
|
|
78
|
+
|
|
74
79
|
/**
|
|
75
80
|
* An adapter that ensures we're using detachedBlobStorage up until we connect to a real service, and then
|
|
76
81
|
* after connecting to a real service augments it with retry and combined summary tree enforcement.
|
|
@@ -84,10 +89,6 @@ export class ContainerStorageAdapter
|
|
|
84
89
|
public constructor(
|
|
85
90
|
detachedBlobStorage: MemoryDetachedBlobStorage | undefined,
|
|
86
91
|
private readonly logger: ITelemetryLoggerExt,
|
|
87
|
-
/**
|
|
88
|
-
* ArrayBufferLikes or utf8 encoded strings, containing blobs from a snapshot
|
|
89
|
-
*/
|
|
90
|
-
private readonly blobContents: { [id: string]: ArrayBufferLike | string } = {},
|
|
91
92
|
private loadingGroupIdSnapshotsFromPendingState:
|
|
92
93
|
| Record<string, SerializedSnapshotInfo>
|
|
93
94
|
| undefined,
|
|
@@ -143,9 +144,9 @@ export class ContainerStorageAdapter
|
|
|
143
144
|
);
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
public
|
|
147
|
-
for (const [id, value] of
|
|
148
|
-
this.blobContents[id]
|
|
147
|
+
public cacheSnapshotBlobs(snapshotBlobs: Map<string, ArrayBuffer>): void {
|
|
148
|
+
for (const [id, value] of snapshotBlobs.entries()) {
|
|
149
|
+
this.blobContents[id] ??= value;
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -220,10 +221,6 @@ export class ContainerStorageAdapter
|
|
|
220
221
|
public async readBlob(id: string): Promise<ArrayBufferLike> {
|
|
221
222
|
const maybeBlob = this.blobContents[id];
|
|
222
223
|
if (maybeBlob !== undefined) {
|
|
223
|
-
if (typeof maybeBlob === "string") {
|
|
224
|
-
const blob = stringToBuffer(maybeBlob, "utf8");
|
|
225
|
-
return blob;
|
|
226
|
-
}
|
|
227
224
|
return maybeBlob;
|
|
228
225
|
}
|
|
229
226
|
return this._storageService.readBlob(id);
|
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
IFluidCodeDetails,
|
|
10
10
|
IContainerPolicies,
|
|
11
11
|
} from "@fluidframework/container-definitions/internal";
|
|
12
|
+
import { LoaderHeader } from "@fluidframework/container-definitions/internal";
|
|
12
13
|
import type {
|
|
13
14
|
FluidObject,
|
|
14
15
|
IConfigProviderBase,
|
|
@@ -20,10 +21,44 @@ import type {
|
|
|
20
21
|
IDocumentServiceFactory,
|
|
21
22
|
IUrlResolver,
|
|
22
23
|
} from "@fluidframework/driver-definitions/internal";
|
|
24
|
+
import { DriverHeader } from "@fluidframework/driver-definitions/internal";
|
|
25
|
+
import {
|
|
26
|
+
GenericError,
|
|
27
|
+
normalizeError,
|
|
28
|
+
createChildMonitoringContext,
|
|
29
|
+
mixinMonitoringContext,
|
|
30
|
+
sessionStorageConfigProvider,
|
|
31
|
+
PerformanceEvent,
|
|
32
|
+
isFluidError,
|
|
33
|
+
} from "@fluidframework/telemetry-utils/internal";
|
|
34
|
+
import { v4 as uuid } from "uuid";
|
|
23
35
|
|
|
36
|
+
import { DebugLogger } from "./debugLogger.js";
|
|
24
37
|
import { createFrozenDocumentServiceFactory } from "./frozenServices.js";
|
|
25
38
|
import { Loader } from "./loader.js";
|
|
39
|
+
import { pkgVersion } from "./packageVersion.js";
|
|
26
40
|
import type { ProtocolHandlerBuilder } from "./protocol.js";
|
|
41
|
+
import type {
|
|
42
|
+
LoadSummarizerSummaryResult,
|
|
43
|
+
OnDemandSummaryResults,
|
|
44
|
+
SummarizeOnDemandResults,
|
|
45
|
+
} from "./summarizerResultTypes.js";
|
|
46
|
+
|
|
47
|
+
interface OnDemandSummarizeResultsPromises {
|
|
48
|
+
readonly summarySubmitted: Promise<SummarizeOnDemandResults["summarySubmitted"]>;
|
|
49
|
+
readonly summaryOpBroadcasted: Promise<SummarizeOnDemandResults["summaryOpBroadcasted"]>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface OnDemandSummarizeOptions {
|
|
53
|
+
readonly reason?: string;
|
|
54
|
+
readonly retryOnFailure?: boolean;
|
|
55
|
+
readonly fullTree?: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface SummarizerLike {
|
|
59
|
+
readonly ISummarizer?: SummarizerLike;
|
|
60
|
+
summarizeOnDemand(options: OnDemandSummarizeOptions): OnDemandSummarizeResultsPromises;
|
|
61
|
+
}
|
|
27
62
|
|
|
28
63
|
/**
|
|
29
64
|
* Properties necessary for creating and loading a container.
|
|
@@ -103,6 +138,15 @@ export interface ILoadExistingContainerProps extends ICreateAndLoadContainerProp
|
|
|
103
138
|
readonly pendingLocalState?: string | undefined;
|
|
104
139
|
}
|
|
105
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Props used to load summarizer container.
|
|
143
|
+
* @legacy @alpha
|
|
144
|
+
*/
|
|
145
|
+
export type ILoadSummarizerContainerProps = Omit<
|
|
146
|
+
ILoadExistingContainerProps,
|
|
147
|
+
"pendingLocalState"
|
|
148
|
+
>;
|
|
149
|
+
|
|
106
150
|
/**
|
|
107
151
|
* Props used to create a detached container.
|
|
108
152
|
* @legacy @beta
|
|
@@ -200,3 +244,133 @@ export async function loadFrozenContainerFromPendingState(
|
|
|
200
244
|
documentServiceFactory: createFrozenDocumentServiceFactory(props.documentServiceFactory),
|
|
201
245
|
});
|
|
202
246
|
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Loads a summarizer container with the required headers, triggers an on-demand summary, and then closes it.
|
|
250
|
+
* Returns success/failure and an optional error for host-side handling.
|
|
251
|
+
*
|
|
252
|
+
* @legacy @alpha
|
|
253
|
+
*/
|
|
254
|
+
export async function loadSummarizerContainerAndMakeSummary(
|
|
255
|
+
loadSummarizerContainerProps: ILoadSummarizerContainerProps,
|
|
256
|
+
): Promise<LoadSummarizerSummaryResult> {
|
|
257
|
+
const { logger, configProvider, request: originalRequest } = loadSummarizerContainerProps;
|
|
258
|
+
const telemetryProps = {
|
|
259
|
+
loaderId: uuid(),
|
|
260
|
+
loaderVersion: pkgVersion,
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
const subMc = mixinMonitoringContext(
|
|
264
|
+
DebugLogger.mixinDebugLogger("fluid:telemetry", logger, {
|
|
265
|
+
all: telemetryProps,
|
|
266
|
+
}),
|
|
267
|
+
sessionStorageConfigProvider.value,
|
|
268
|
+
configProvider,
|
|
269
|
+
);
|
|
270
|
+
const mc = createChildMonitoringContext({
|
|
271
|
+
logger: subMc.logger,
|
|
272
|
+
namespace: "SummarizerOnDemand",
|
|
273
|
+
});
|
|
274
|
+
return PerformanceEvent.timedExecAsync(
|
|
275
|
+
mc.logger,
|
|
276
|
+
{ eventName: "SummarizerOnDemandSummary" },
|
|
277
|
+
async (event) => {
|
|
278
|
+
const baseHeaders = originalRequest.headers;
|
|
279
|
+
const request = {
|
|
280
|
+
...originalRequest,
|
|
281
|
+
headers: {
|
|
282
|
+
...baseHeaders,
|
|
283
|
+
[LoaderHeader.cache]: false,
|
|
284
|
+
[LoaderHeader.clientDetails]: {
|
|
285
|
+
capabilities: { interactive: false },
|
|
286
|
+
type: "summarizer",
|
|
287
|
+
},
|
|
288
|
+
[DriverHeader.summarizingClient]: true,
|
|
289
|
+
[LoaderHeader.reconnect]: false,
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
const container = await loadExistingContainer({
|
|
294
|
+
...loadSummarizerContainerProps,
|
|
295
|
+
request,
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
let summarySubmitted: SummarizeOnDemandResults["summarySubmitted"];
|
|
299
|
+
let summaryOpBroadcasted: SummarizeOnDemandResults["summaryOpBroadcasted"];
|
|
300
|
+
try {
|
|
301
|
+
if (container.getEntryPoint === undefined) {
|
|
302
|
+
throw new GenericError("container.getEntryPoint() is undefined");
|
|
303
|
+
}
|
|
304
|
+
const fluidObject = (await container.getEntryPoint()) as FluidObject<SummarizerLike>;
|
|
305
|
+
const summarizer = fluidObject?.ISummarizer;
|
|
306
|
+
if (summarizer === undefined) {
|
|
307
|
+
throw new GenericError("Summarizer entry point not available");
|
|
308
|
+
}
|
|
309
|
+
// Host controlled feature gate for fullTree
|
|
310
|
+
// Default value will be false
|
|
311
|
+
const fullTreeGate =
|
|
312
|
+
mc.config.getBoolean("Fluid.Summarizer.FullTree.OnDemand") === true;
|
|
313
|
+
|
|
314
|
+
const summarizeResults: OnDemandSummarizeResultsPromises =
|
|
315
|
+
summarizer.summarizeOnDemand({
|
|
316
|
+
reason: "summaryOnRequest",
|
|
317
|
+
retryOnFailure: true,
|
|
318
|
+
fullTree: fullTreeGate,
|
|
319
|
+
});
|
|
320
|
+
[summarySubmitted, summaryOpBroadcasted] = await Promise.all([
|
|
321
|
+
summarizeResults.summarySubmitted,
|
|
322
|
+
summarizeResults.summaryOpBroadcasted,
|
|
323
|
+
]);
|
|
324
|
+
|
|
325
|
+
const summaryResults: OnDemandSummaryResults = {
|
|
326
|
+
summarySubmitted: summarySubmitted.success,
|
|
327
|
+
summaryInfo: summarySubmitted.success
|
|
328
|
+
? {
|
|
329
|
+
stage: summarySubmitted.data.stage,
|
|
330
|
+
handle: summaryOpBroadcasted.success
|
|
331
|
+
? summaryOpBroadcasted.data.summarizeOp.contents.handle
|
|
332
|
+
: undefined,
|
|
333
|
+
}
|
|
334
|
+
: {},
|
|
335
|
+
summaryOpBroadcasted: summaryOpBroadcasted.success,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
if (summarySubmitted.success && summaryOpBroadcasted.success) {
|
|
339
|
+
event.end({
|
|
340
|
+
success: true,
|
|
341
|
+
summarySubmitted: true,
|
|
342
|
+
summaryOpBroadcasted: true,
|
|
343
|
+
});
|
|
344
|
+
return {
|
|
345
|
+
success: true,
|
|
346
|
+
summaryResults,
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const failureError =
|
|
351
|
+
summarySubmitted.success === false
|
|
352
|
+
? summarySubmitted.error
|
|
353
|
+
: summaryOpBroadcasted.success === false
|
|
354
|
+
? summaryOpBroadcasted.error
|
|
355
|
+
: new GenericError("On demand summary failed");
|
|
356
|
+
|
|
357
|
+
event.end({
|
|
358
|
+
success: false,
|
|
359
|
+
summarySubmitted: summarySubmitted.success,
|
|
360
|
+
summaryOpBroadcasted: summaryOpBroadcasted.success,
|
|
361
|
+
});
|
|
362
|
+
return {
|
|
363
|
+
success: false,
|
|
364
|
+
error: failureError,
|
|
365
|
+
};
|
|
366
|
+
} catch (error) {
|
|
367
|
+
event.cancel({ success: false }, error);
|
|
368
|
+
const caughtError = isFluidError(error) ? error : normalizeError(error);
|
|
369
|
+
return { success: false, error: caughtError };
|
|
370
|
+
} finally {
|
|
371
|
+
container.dispose();
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
{ start: true, end: true, cancel: "generic" },
|
|
375
|
+
);
|
|
376
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -11,12 +11,19 @@ export {
|
|
|
11
11
|
loadExistingContainer,
|
|
12
12
|
rehydrateDetachedContainer,
|
|
13
13
|
loadFrozenContainerFromPendingState,
|
|
14
|
+
loadSummarizerContainerAndMakeSummary,
|
|
14
15
|
type ICreateAndLoadContainerProps,
|
|
15
16
|
type ICreateDetachedContainerProps,
|
|
16
17
|
type ILoadExistingContainerProps,
|
|
18
|
+
type ILoadSummarizerContainerProps,
|
|
17
19
|
type IRehydrateDetachedContainerProps,
|
|
18
20
|
type ILoadFrozenContainerFromPendingStateProps,
|
|
19
21
|
} from "./createAndLoadContainerUtils.js";
|
|
22
|
+
export type {
|
|
23
|
+
LoadSummarizerSummaryResult,
|
|
24
|
+
OnDemandSummaryResults,
|
|
25
|
+
SummaryStage,
|
|
26
|
+
} from "./summarizerResultTypes.js";
|
|
20
27
|
export {
|
|
21
28
|
type ICodeDetailsLoader,
|
|
22
29
|
type IFluidModuleWithDetails,
|
package/src/packageVersion.ts
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
|
|
33
33
|
import {
|
|
34
34
|
getBlobContentsFromTree,
|
|
35
|
+
type ContainerStorageAdapter,
|
|
35
36
|
type ISerializableBlobContents,
|
|
36
37
|
} from "./containerStorageAdapter.js";
|
|
37
38
|
import {
|
|
@@ -133,8 +134,8 @@ interface ISnapshotInfo {
|
|
|
133
134
|
}
|
|
134
135
|
|
|
135
136
|
export type ISerializedStateManagerDocumentStorageService = Pick<
|
|
136
|
-
|
|
137
|
-
"getSnapshot" | "getSnapshotTree" | "getVersions" | "readBlob"
|
|
137
|
+
ContainerStorageAdapter,
|
|
138
|
+
"getSnapshot" | "getSnapshotTree" | "getVersions" | "readBlob" | "cacheSnapshotBlobs"
|
|
138
139
|
> & {
|
|
139
140
|
loadedGroupIdSnapshots: Record<string, ISnapshot>;
|
|
140
141
|
};
|
|
@@ -300,11 +301,13 @@ export class SerializedStateManager implements IDisposable {
|
|
|
300
301
|
return { snapshot, version, attributes };
|
|
301
302
|
} else {
|
|
302
303
|
const { baseSnapshot, snapshotBlobs, savedOps } = pendingLocalState;
|
|
303
|
-
const attributes = await getDocumentAttributes(this.storageAdapter, baseSnapshot);
|
|
304
304
|
const blobContents = new Map<string, ArrayBuffer>();
|
|
305
305
|
for (const [id, value] of Object.entries(snapshotBlobs)) {
|
|
306
306
|
blobContents.set(id, stringToBuffer(value, "utf8"));
|
|
307
307
|
}
|
|
308
|
+
this.storageAdapter.cacheSnapshotBlobs(blobContents);
|
|
309
|
+
const attributes = await getDocumentAttributes(this.storageAdapter, baseSnapshot);
|
|
310
|
+
|
|
308
311
|
const snapshot: ISnapshot = {
|
|
309
312
|
sequenceNumber: attributes.sequenceNumber,
|
|
310
313
|
snapshotTree: baseSnapshot,
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { IErrorBase } from "@fluidframework/core-interfaces";
|
|
7
|
+
import type {
|
|
8
|
+
ISequencedDocumentMessage,
|
|
9
|
+
ISummaryAck,
|
|
10
|
+
ISummaryContent,
|
|
11
|
+
ISummaryTree,
|
|
12
|
+
MessageType,
|
|
13
|
+
} from "@fluidframework/driver-definitions/internal";
|
|
14
|
+
|
|
15
|
+
export const summarizerRequestUrl = "_summarizer";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Stages of summary process.
|
|
19
|
+
*
|
|
20
|
+
* Stages:
|
|
21
|
+
*
|
|
22
|
+
* 1. "base" - stopped before the summary tree was even generated, and the result only contains the base data
|
|
23
|
+
*
|
|
24
|
+
* 2. "generate" - the summary tree was generated, and the result will contain that tree + stats
|
|
25
|
+
*
|
|
26
|
+
* 3. "upload" - the summary was uploaded to storage, and the result contains the server-provided handle
|
|
27
|
+
*
|
|
28
|
+
* 4. "submit" - the summarize op was submitted, and the result contains the op client sequence number.
|
|
29
|
+
*
|
|
30
|
+
* @legacy @alpha
|
|
31
|
+
*/
|
|
32
|
+
export type SummaryStage = "base" | "generate" | "upload" | "submit" | "unknown";
|
|
33
|
+
|
|
34
|
+
type OnDemandSummaryStageResult<TSuccess> =
|
|
35
|
+
| {
|
|
36
|
+
readonly success: true;
|
|
37
|
+
readonly data: TSuccess;
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
readonly success: false;
|
|
41
|
+
readonly error: IErrorBase;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
interface ISummaryOpMessage extends ISequencedDocumentMessage {
|
|
45
|
+
type: MessageType.Summarize;
|
|
46
|
+
contents: ISummaryContent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ISummaryAckMessage extends ISequencedDocumentMessage {
|
|
50
|
+
type: MessageType.SummaryAck;
|
|
51
|
+
contents: ISummaryAck;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @internal
|
|
56
|
+
*/
|
|
57
|
+
export interface SummarizeOnDemandResults {
|
|
58
|
+
readonly summarySubmitted: OnDemandSummaryStageResult<{
|
|
59
|
+
readonly stage: SummaryStage;
|
|
60
|
+
readonly summaryTree?: ISummaryTree;
|
|
61
|
+
readonly handle?: string;
|
|
62
|
+
}>;
|
|
63
|
+
readonly summaryOpBroadcasted: OnDemandSummaryStageResult<{
|
|
64
|
+
readonly broadcastDuration: number;
|
|
65
|
+
readonly summarizeOp: ISummaryOpMessage;
|
|
66
|
+
}>;
|
|
67
|
+
readonly receivedSummaryAckOrNack: OnDemandSummaryStageResult<{
|
|
68
|
+
readonly summaryAckOp: ISummaryAckMessage;
|
|
69
|
+
readonly ackNackDuration: number;
|
|
70
|
+
}>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Results from an on-demand summary request.
|
|
75
|
+
* @legacy @alpha
|
|
76
|
+
*/
|
|
77
|
+
export interface OnDemandSummaryResults {
|
|
78
|
+
/**
|
|
79
|
+
* True if summary was generated, uploaded, and submitted.
|
|
80
|
+
*/
|
|
81
|
+
readonly summarySubmitted: boolean;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Information about the summary that was submitted, if any.
|
|
85
|
+
*/
|
|
86
|
+
readonly summaryInfo: {
|
|
87
|
+
/**
|
|
88
|
+
* Stage at which summary process ended.
|
|
89
|
+
*/
|
|
90
|
+
readonly stage?: SummaryStage;
|
|
91
|
+
/**
|
|
92
|
+
* Handle of the complete summary.
|
|
93
|
+
*/
|
|
94
|
+
readonly handle?: string;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* True if summarize op broadcast was observed.
|
|
99
|
+
*/
|
|
100
|
+
readonly summaryOpBroadcasted: boolean;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Outcome from {@link loadSummarizerContainerAndMakeSummary}.
|
|
105
|
+
* @legacy @alpha
|
|
106
|
+
*/
|
|
107
|
+
export type LoadSummarizerSummaryResult =
|
|
108
|
+
| {
|
|
109
|
+
readonly success: true;
|
|
110
|
+
readonly summaryResults: OnDemandSummaryResults;
|
|
111
|
+
}
|
|
112
|
+
| {
|
|
113
|
+
readonly success: false;
|
|
114
|
+
readonly error: IErrorBase;
|
|
115
|
+
};
|
package/src/utils.ts
CHANGED
|
@@ -274,33 +274,34 @@ export function getProtocolSnapshotTree(snapshot: ISnapshotTree): ISnapshotTree
|
|
|
274
274
|
return ".protocol" in snapshot.trees ? snapshot.trees[".protocol"] : snapshot;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
export const combineSnapshotTreeAndSnapshotBlobs = (
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
): ISnapshotTreeWithBlobContents => {
|
|
281
|
-
const
|
|
277
|
+
export const combineSnapshotTreeAndSnapshotBlobs = ({
|
|
278
|
+
blobContents,
|
|
279
|
+
snapshotTree,
|
|
280
|
+
}: Pick<ISnapshot, "blobContents" | "snapshotTree">): ISnapshotTreeWithBlobContents => {
|
|
281
|
+
const currentTreeBlobs: { [path: string]: ArrayBufferLike } = {};
|
|
282
282
|
|
|
283
283
|
// Process blobs in the current level
|
|
284
|
-
for (const [, id] of Object.entries(
|
|
285
|
-
|
|
286
|
-
|
|
284
|
+
for (const [, id] of Object.entries(snapshotTree.blobs)) {
|
|
285
|
+
const blob = blobContents.get(id);
|
|
286
|
+
if (blob !== undefined) {
|
|
287
|
+
currentTreeBlobs[id] = blob;
|
|
287
288
|
}
|
|
288
289
|
}
|
|
289
290
|
|
|
290
291
|
// Recursively process trees in the current level
|
|
291
292
|
const trees: { [path: string]: ISnapshotTreeWithBlobContents } = {};
|
|
292
|
-
for (const [path, tree] of Object.entries(
|
|
293
|
-
trees[path] = combineSnapshotTreeAndSnapshotBlobs(tree,
|
|
293
|
+
for (const [path, tree] of Object.entries(snapshotTree.trees)) {
|
|
294
|
+
trees[path] = combineSnapshotTreeAndSnapshotBlobs({ snapshotTree: tree, blobContents });
|
|
294
295
|
}
|
|
295
296
|
|
|
296
297
|
// Create a new snapshot tree with blob contents and processed trees
|
|
297
|
-
const
|
|
298
|
-
...
|
|
299
|
-
blobsContents,
|
|
298
|
+
const snapshot: ISnapshotTreeWithBlobContents = {
|
|
299
|
+
...snapshotTree,
|
|
300
|
+
blobsContents: currentTreeBlobs,
|
|
300
301
|
trees,
|
|
301
302
|
};
|
|
302
303
|
|
|
303
|
-
return
|
|
304
|
+
return snapshot;
|
|
304
305
|
};
|
|
305
306
|
|
|
306
307
|
export function isDeltaStreamConnectionForbiddenError(
|