@fluidframework/runtime-utils 2.0.0-rc.1.0.4 → 2.0.0-rc.2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{.eslintrc.js → .eslintrc.cjs} +4 -1
- package/{.mocharc.js → .mocharc.cjs} +1 -1
- package/CHANGELOG.md +30 -0
- package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
- package/api-extractor-lint.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/runtime-utils.api.md +10 -11
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -39
- package/dist/index.js.map +1 -1
- package/dist/package.json +3 -0
- package/dist/runtime-utils-alpha.d.ts +5 -3
- package/dist/runtime-utils-beta.d.ts +5 -3
- package/dist/runtime-utils-public.d.ts +5 -3
- package/dist/runtime-utils-untrimmed.d.ts +34 -9
- package/dist/summaryUtils.d.ts +18 -8
- package/dist/summaryUtils.d.ts.map +1 -1
- package/dist/summaryUtils.js +34 -9
- package/dist/summaryUtils.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/dist/utils.d.ts +14 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +49 -1
- package/dist/utils.js.map +1 -1
- package/lib/{dataStoreHandleContextUtils.d.mts → dataStoreHandleContextUtils.d.ts} +1 -1
- package/lib/dataStoreHandleContextUtils.d.ts.map +1 -0
- package/lib/{dataStoreHandleContextUtils.mjs → dataStoreHandleContextUtils.js} +1 -1
- package/lib/dataStoreHandleContextUtils.js.map +1 -0
- package/lib/{dataStoreHelpers.d.mts → dataStoreHelpers.d.ts} +1 -1
- package/lib/dataStoreHelpers.d.ts.map +1 -0
- package/lib/{dataStoreHelpers.mjs → dataStoreHelpers.js} +1 -1
- package/lib/dataStoreHelpers.js.map +1 -0
- package/lib/{handles.d.mts → handles.d.ts} +1 -1
- package/lib/handles.d.ts.map +1 -0
- package/lib/{handles.mjs → handles.js} +1 -1
- package/lib/handles.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +15 -0
- package/lib/index.js.map +1 -0
- package/lib/{objectstoragepartition.d.mts → objectstoragepartition.d.ts} +1 -1
- package/lib/objectstoragepartition.d.ts.map +1 -0
- package/lib/{objectstoragepartition.mjs → objectstoragepartition.js} +1 -1
- package/lib/objectstoragepartition.js.map +1 -0
- package/lib/{objectstorageutils.d.mts → objectstorageutils.d.ts} +1 -1
- package/lib/objectstorageutils.d.ts.map +1 -0
- package/lib/{objectstorageutils.mjs → objectstorageutils.js} +1 -1
- package/lib/objectstorageutils.js.map +1 -0
- package/lib/{requestParser.d.mts → requestParser.d.ts} +5 -1
- package/lib/requestParser.d.ts.map +1 -0
- package/lib/{requestParser.mjs → requestParser.js} +1 -1
- package/lib/requestParser.js.map +1 -0
- package/lib/{runtime-utils-alpha.d.mts → runtime-utils-alpha.d.ts} +5 -3
- package/lib/{runtime-utils-beta.d.mts → runtime-utils-beta.d.ts} +5 -3
- package/lib/{runtime-utils-public.d.mts → runtime-utils-public.d.ts} +5 -3
- package/lib/{runtime-utils-untrimmed.d.mts → runtime-utils-untrimmed.d.ts} +34 -9
- package/lib/{runtimeFactoryHelper.d.mts → runtimeFactoryHelper.d.ts} +1 -1
- package/lib/runtimeFactoryHelper.d.ts.map +1 -0
- package/lib/{runtimeFactoryHelper.mjs → runtimeFactoryHelper.js} +1 -1
- package/lib/runtimeFactoryHelper.js.map +1 -0
- package/lib/{summaryUtils.d.mts → summaryUtils.d.ts} +19 -9
- package/lib/summaryUtils.d.ts.map +1 -0
- package/lib/{summaryUtils.mjs → summaryUtils.js} +34 -9
- package/lib/summaryUtils.js.map +1 -0
- package/lib/test/dataStoreHelpers.spec.js +29 -0
- package/lib/test/dataStoreHelpers.spec.js.map +1 -0
- package/lib/test/requestParser.spec.js +111 -0
- package/lib/test/requestParser.spec.js.map +1 -0
- package/lib/test/runtimeFactoryHelper.spec.js +44 -0
- package/lib/test/runtimeFactoryHelper.spec.js.map +1 -0
- package/lib/test/summaryUtils.spec.js +283 -0
- package/lib/test/summaryUtils.spec.js.map +1 -0
- package/lib/test/types/validateRuntimeUtilsPrevious.generated.js +58 -0
- package/lib/test/types/validateRuntimeUtilsPrevious.generated.js.map +1 -0
- package/lib/test/utils.spec.js +65 -0
- package/lib/test/utils.spec.js.map +1 -0
- package/lib/{unpackUsedRoutes.d.mts → unpackUsedRoutes.d.ts} +1 -1
- package/lib/unpackUsedRoutes.d.ts.map +1 -0
- package/lib/{unpackUsedRoutes.mjs → unpackUsedRoutes.js} +1 -1
- package/lib/unpackUsedRoutes.js.map +1 -0
- package/lib/utils.d.ts +34 -0
- package/lib/utils.d.ts.map +1 -0
- package/lib/utils.js +64 -0
- package/lib/utils.js.map +1 -0
- package/package.json +48 -49
- package/src/index.ts +11 -11
- package/src/summaryUtils.ts +48 -18
- package/src/utils.ts +48 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +2 -5
- package/lib/dataStoreHandleContextUtils.d.mts.map +0 -1
- package/lib/dataStoreHandleContextUtils.mjs.map +0 -1
- package/lib/dataStoreHelpers.d.mts.map +0 -1
- package/lib/dataStoreHelpers.mjs.map +0 -1
- package/lib/handles.d.mts.map +0 -1
- package/lib/handles.mjs.map +0 -1
- package/lib/index.d.mts +0 -15
- package/lib/index.d.mts.map +0 -1
- package/lib/index.mjs +0 -15
- package/lib/index.mjs.map +0 -1
- package/lib/objectstoragepartition.d.mts.map +0 -1
- package/lib/objectstoragepartition.mjs.map +0 -1
- package/lib/objectstorageutils.d.mts.map +0 -1
- package/lib/objectstorageutils.mjs.map +0 -1
- package/lib/requestParser.d.mts.map +0 -1
- package/lib/requestParser.mjs.map +0 -1
- package/lib/runtimeFactoryHelper.d.mts.map +0 -1
- package/lib/runtimeFactoryHelper.mjs.map +0 -1
- package/lib/summaryUtils.d.mts.map +0 -1
- package/lib/summaryUtils.mjs.map +0 -1
- package/lib/unpackUsedRoutes.d.mts.map +0 -1
- package/lib/unpackUsedRoutes.mjs.map +0 -1
- package/lib/utils.d.mts +0 -20
- package/lib/utils.d.mts.map +0 -1
- package/lib/utils.mjs +0 -17
- package/lib/utils.mjs.map +0 -1
|
@@ -22,14 +22,12 @@ import { ITelemetryContext } from '@fluidframework/runtime-definitions';
|
|
|
22
22
|
import { ITree } from '@fluidframework/protocol-definitions';
|
|
23
23
|
import { SummaryObject } from '@fluidframework/protocol-definitions';
|
|
24
24
|
import { SummaryType } from '@fluidframework/protocol-definitions';
|
|
25
|
-
import {
|
|
25
|
+
import type { TelemetryBaseEventPropertyType } from '@fluidframework/core-interfaces';
|
|
26
26
|
|
|
27
27
|
/* Excluded from this release type: addBlobToSummary */
|
|
28
28
|
|
|
29
29
|
/* Excluded from this release type: addSummarizeResultToSummary */
|
|
30
30
|
|
|
31
|
-
/* Excluded from this release type: addTreeToSummary */
|
|
32
|
-
|
|
33
31
|
/* Excluded from this release type: calculateStats */
|
|
34
32
|
|
|
35
33
|
/* Excluded from this release type: convertSnapshotTreeToSummaryTree */
|
|
@@ -46,6 +44,8 @@ import { TelemetryEventPropertyType } from '@fluidframework/core-interfaces';
|
|
|
46
44
|
|
|
47
45
|
/* Excluded from this release type: createResponseError */
|
|
48
46
|
|
|
47
|
+
/* Excluded from this release type: encodeCompactIdToString */
|
|
48
|
+
|
|
49
49
|
/* Excluded from this release type: exceptionToResponse */
|
|
50
50
|
|
|
51
51
|
/* Excluded from this release type: Factory */
|
|
@@ -86,6 +86,8 @@ import { TelemetryEventPropertyType } from '@fluidframework/core-interfaces';
|
|
|
86
86
|
|
|
87
87
|
/* Excluded from this release type: ObjectStoragePartition */
|
|
88
88
|
|
|
89
|
+
/* Excluded from this release type: processAttachMessageGCData */
|
|
90
|
+
|
|
89
91
|
/* Excluded from this release type: ReadAndParseBlob */
|
|
90
92
|
|
|
91
93
|
/* Excluded from this release type: RequestParser */
|
|
@@ -22,14 +22,12 @@ import { ITelemetryContext } from '@fluidframework/runtime-definitions';
|
|
|
22
22
|
import { ITree } from '@fluidframework/protocol-definitions';
|
|
23
23
|
import { SummaryObject } from '@fluidframework/protocol-definitions';
|
|
24
24
|
import { SummaryType } from '@fluidframework/protocol-definitions';
|
|
25
|
-
import {
|
|
25
|
+
import type { TelemetryBaseEventPropertyType } from '@fluidframework/core-interfaces';
|
|
26
26
|
|
|
27
27
|
/* Excluded from this release type: addBlobToSummary */
|
|
28
28
|
|
|
29
29
|
/* Excluded from this release type: addSummarizeResultToSummary */
|
|
30
30
|
|
|
31
|
-
/* Excluded from this release type: addTreeToSummary */
|
|
32
|
-
|
|
33
31
|
/* Excluded from this release type: calculateStats */
|
|
34
32
|
|
|
35
33
|
/* Excluded from this release type: convertSnapshotTreeToSummaryTree */
|
|
@@ -46,6 +44,8 @@ import { TelemetryEventPropertyType } from '@fluidframework/core-interfaces';
|
|
|
46
44
|
|
|
47
45
|
/* Excluded from this release type: createResponseError */
|
|
48
46
|
|
|
47
|
+
/* Excluded from this release type: encodeCompactIdToString */
|
|
48
|
+
|
|
49
49
|
/* Excluded from this release type: exceptionToResponse */
|
|
50
50
|
|
|
51
51
|
/* Excluded from this release type: Factory */
|
|
@@ -86,6 +86,8 @@ import { TelemetryEventPropertyType } from '@fluidframework/core-interfaces';
|
|
|
86
86
|
|
|
87
87
|
/* Excluded from this release type: ObjectStoragePartition */
|
|
88
88
|
|
|
89
|
+
/* Excluded from this release type: processAttachMessageGCData */
|
|
90
|
+
|
|
89
91
|
/* Excluded from this release type: ReadAndParseBlob */
|
|
90
92
|
|
|
91
93
|
/* Excluded from this release type: RequestParser */
|
|
@@ -22,7 +22,7 @@ import { ITelemetryContext } from '@fluidframework/runtime-definitions';
|
|
|
22
22
|
import { ITree } from '@fluidframework/protocol-definitions';
|
|
23
23
|
import { SummaryObject } from '@fluidframework/protocol-definitions';
|
|
24
24
|
import { SummaryType } from '@fluidframework/protocol-definitions';
|
|
25
|
-
import {
|
|
25
|
+
import type { TelemetryBaseEventPropertyType } from '@fluidframework/core-interfaces';
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @internal
|
|
@@ -34,11 +34,6 @@ export declare function addBlobToSummary(summary: ISummaryTreeWithStats, key: st
|
|
|
34
34
|
*/
|
|
35
35
|
export declare function addSummarizeResultToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void;
|
|
36
36
|
|
|
37
|
-
/**
|
|
38
|
-
* @internal
|
|
39
|
-
*/
|
|
40
|
-
export declare function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void;
|
|
41
|
-
|
|
42
37
|
/**
|
|
43
38
|
* @internal
|
|
44
39
|
*/
|
|
@@ -92,6 +87,21 @@ export declare function createResponseError(status: number, value: string, reque
|
|
|
92
87
|
[key: string]: any;
|
|
93
88
|
}): IResponse;
|
|
94
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Encode compact ID (returned by IContainerRuntime.generateDocumentUniqueId()) to a compact string representation.
|
|
92
|
+
* While this is the main usage pattern, it works with any non-negative integer or a string.
|
|
93
|
+
* Strings are retured as is, and assumed to be UUIDs, i.e. unique enough to never overlap with
|
|
94
|
+
* numbers encoded as strings by this function. Any other strings are likely to run into collisions and should not be used!
|
|
95
|
+
* This function is useful in places where we serialize resulting ID as string and use them as strings, thus we are not
|
|
96
|
+
* gaining any efficiency from having a number type.
|
|
97
|
+
* We do not provide a decode function, so this API is only useful only result is stored and there is no need to go back to origianl form.
|
|
98
|
+
* @param idArg - input - either a non-negative integer or a string. Strings are returned as is, while numbers are encoded in compat form
|
|
99
|
+
* @param prefix - optinal string prefix
|
|
100
|
+
* @returns A string - representation of an input
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
export declare function encodeCompactIdToString(idArg: number | string, prefix?: string): string;
|
|
104
|
+
|
|
95
105
|
/**
|
|
96
106
|
* @internal
|
|
97
107
|
*/
|
|
@@ -191,6 +201,21 @@ export declare class ObjectStoragePartition implements IChannelStorageService {
|
|
|
191
201
|
list(path: string): Promise<string[]>;
|
|
192
202
|
}
|
|
193
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Looks in the given attach message snapshot for the .gcdata blob, which would
|
|
206
|
+
* contain the initial GC Data for the node being attached.
|
|
207
|
+
* If it finds it, it notifies GC of all the new outbound routes being added by the attach.
|
|
208
|
+
*
|
|
209
|
+
* @param snapshot - The snapshot from the attach message
|
|
210
|
+
* @param addedGCOutboundRoute - Callback to notify GC of a new outbound route.
|
|
211
|
+
* IMPORTANT: addedGCOutboundRoute's param nodeId is "/" for the attaching node itself, or "/<id>" for its children.
|
|
212
|
+
*
|
|
213
|
+
* @returns true if it found/processed GC Data, false otherwise
|
|
214
|
+
*
|
|
215
|
+
* @internal
|
|
216
|
+
*/
|
|
217
|
+
export declare function processAttachMessageGCData(snapshot: ITree | null, addedGCOutboundRoute: (fromNodeId: string, toPath: string) => void): boolean;
|
|
218
|
+
|
|
194
219
|
/**
|
|
195
220
|
* Reads a blob from storage and parses it from JSON.
|
|
196
221
|
*
|
|
@@ -290,15 +315,15 @@ export declare class TelemetryContext implements ITelemetryContext {
|
|
|
290
315
|
/**
|
|
291
316
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.set}
|
|
292
317
|
*/
|
|
293
|
-
set(prefix: string, property: string, value:
|
|
318
|
+
set(prefix: string, property: string, value: TelemetryBaseEventPropertyType): void;
|
|
294
319
|
/**
|
|
295
320
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.setMultiple}
|
|
296
321
|
*/
|
|
297
|
-
setMultiple(prefix: string, property: string, values: Record<string,
|
|
322
|
+
setMultiple(prefix: string, property: string, values: Record<string, TelemetryBaseEventPropertyType>): void;
|
|
298
323
|
/**
|
|
299
324
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.get}
|
|
300
325
|
*/
|
|
301
|
-
get(prefix: string, property: string):
|
|
326
|
+
get(prefix: string, property: string): TelemetryBaseEventPropertyType;
|
|
302
327
|
/**
|
|
303
328
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.serialize}
|
|
304
329
|
*/
|
|
@@ -15,4 +15,4 @@ export declare abstract class RuntimeFactoryHelper<T = IContainerRuntime> implem
|
|
|
15
15
|
instantiateFromExisting(_runtime: T): Promise<void>;
|
|
16
16
|
hasInitialized(_runtime: T): Promise<void>;
|
|
17
17
|
}
|
|
18
|
-
//# sourceMappingURL=runtimeFactoryHelper.d.
|
|
18
|
+
//# sourceMappingURL=runtimeFactoryHelper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeFactoryHelper.d.ts","sourceRoot":"","sources":["../src/runtimeFactoryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AAElF;;GAEG;AACH,8BAAsB,oBAAoB,CAAC,CAAC,GAAG,iBAAiB,CAAE,YAAW,eAAe;IAC3F,IAAW,eAAe,SAEzB;IAEY,kBAAkB,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,CAAC;aASJ,aAAa,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACX,oBAAoB,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAChD,uBAAuB,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IACnD,cAAc,CAAC,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeFactoryHelper.js","sourceRoot":"","sources":["../src/runtimeFactoryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH;;GAEG;AACH,MAAM,OAAgB,oBAAoB;IACzC,IAAW,eAAe;QACzB,OAAO,IAAI,CAAC;IACb,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAC9B,OAA0B,EAC1B,QAAiB;QAEjB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5D,MAAM,CAAC,QAAQ;YACd,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,OAAO,CAAC;IAChB,CAAC;IAMM,KAAK,CAAC,oBAAoB,CAAC,QAAW,IAAkB,CAAC;IACzD,KAAK,CAAC,uBAAuB,CAAC,QAAW,IAAkB,CAAC;IAC5D,KAAK,CAAC,cAAc,CAAC,QAAW,IAAkB,CAAC;CAC1D","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIContainerContext,\n\tIRuntime,\n\tIRuntimeFactory,\n} from \"@fluidframework/container-definitions\";\nimport { IContainerRuntime } from \"@fluidframework/container-runtime-definitions\";\n\n/**\n * @alpha\n */\nexport abstract class RuntimeFactoryHelper<T = IContainerRuntime> implements IRuntimeFactory {\n\tpublic get IRuntimeFactory() {\n\t\treturn this;\n\t}\n\n\tpublic async instantiateRuntime(\n\t\tcontext: IContainerContext,\n\t\texisting: boolean,\n\t): Promise<IRuntime> {\n\t\tconst runtime = await this.preInitialize(context, existing);\n\t\tawait (existing\n\t\t\t? this.instantiateFromExisting(runtime)\n\t\t\t: this.instantiateFirstTime(runtime));\n\t\tawait this.hasInitialized(runtime);\n\t\treturn runtime;\n\t}\n\n\tpublic abstract preInitialize(\n\t\tcontext: IContainerContext,\n\t\texisting: boolean,\n\t): Promise<IRuntime & T>;\n\tpublic async instantiateFirstTime(_runtime: T): Promise<void> {}\n\tpublic async instantiateFromExisting(_runtime: T): Promise<void> {}\n\tpublic async hasInitialized(_runtime: T): Promise<void> {}\n}\n"]}
|
|
@@ -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 {
|
|
5
|
+
import type { TelemetryBaseEventPropertyType } from "@fluidframework/core-interfaces";
|
|
6
6
|
import { ITree, SummaryType, ISummaryTree, SummaryObject, ISummaryBlob } from "@fluidframework/protocol-definitions";
|
|
7
7
|
import { ISummaryStats, ISummarizeResult, ISummaryTreeWithStats, ITelemetryContext, IGarbageCollectionData } from "@fluidframework/runtime-definitions";
|
|
8
8
|
import { ISnapshotTreeWithBlobContents } from "@fluidframework/container-definitions";
|
|
@@ -29,10 +29,6 @@ export declare function calculateStats(summary: SummaryObject): ISummaryStats;
|
|
|
29
29
|
* @internal
|
|
30
30
|
*/
|
|
31
31
|
export declare function addBlobToSummary(summary: ISummaryTreeWithStats, key: string, content: string | Uint8Array): void;
|
|
32
|
-
/**
|
|
33
|
-
* @internal
|
|
34
|
-
*/
|
|
35
|
-
export declare function addTreeToSummary(summary: ISummaryTreeWithStats, key: string, summarizeResult: ISummarizeResult): void;
|
|
36
32
|
/**
|
|
37
33
|
* @internal
|
|
38
34
|
*/
|
|
@@ -80,6 +76,20 @@ export declare function convertSnapshotTreeToSummaryTree(snapshot: ISnapshotTree
|
|
|
80
76
|
* @internal
|
|
81
77
|
*/
|
|
82
78
|
export declare function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree;
|
|
79
|
+
/**
|
|
80
|
+
* Looks in the given attach message snapshot for the .gcdata blob, which would
|
|
81
|
+
* contain the initial GC Data for the node being attached.
|
|
82
|
+
* If it finds it, it notifies GC of all the new outbound routes being added by the attach.
|
|
83
|
+
*
|
|
84
|
+
* @param snapshot - The snapshot from the attach message
|
|
85
|
+
* @param addedGCOutboundRoute - Callback to notify GC of a new outbound route.
|
|
86
|
+
* IMPORTANT: addedGCOutboundRoute's param nodeId is "/" for the attaching node itself, or "/<id>" for its children.
|
|
87
|
+
*
|
|
88
|
+
* @returns true if it found/processed GC Data, false otherwise
|
|
89
|
+
*
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
export declare function processAttachMessageGCData(snapshot: ITree | null, addedGCOutboundRoute: (fromNodeId: string, toPath: string) => void): boolean;
|
|
83
93
|
/**
|
|
84
94
|
* @internal
|
|
85
95
|
*/
|
|
@@ -88,15 +98,15 @@ export declare class TelemetryContext implements ITelemetryContext {
|
|
|
88
98
|
/**
|
|
89
99
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.set}
|
|
90
100
|
*/
|
|
91
|
-
set(prefix: string, property: string, value:
|
|
101
|
+
set(prefix: string, property: string, value: TelemetryBaseEventPropertyType): void;
|
|
92
102
|
/**
|
|
93
103
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.setMultiple}
|
|
94
104
|
*/
|
|
95
|
-
setMultiple(prefix: string, property: string, values: Record<string,
|
|
105
|
+
setMultiple(prefix: string, property: string, values: Record<string, TelemetryBaseEventPropertyType>): void;
|
|
96
106
|
/**
|
|
97
107
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.get}
|
|
98
108
|
*/
|
|
99
|
-
get(prefix: string, property: string):
|
|
109
|
+
get(prefix: string, property: string): TelemetryBaseEventPropertyType;
|
|
100
110
|
/**
|
|
101
111
|
* {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.serialize}
|
|
102
112
|
*/
|
|
@@ -130,4 +140,4 @@ export declare class GCDataBuilder implements IGarbageCollectionData {
|
|
|
130
140
|
addRouteToAllNodes(outboundRoute: string): void;
|
|
131
141
|
getGCData(): IGarbageCollectionData;
|
|
132
142
|
}
|
|
133
|
-
//# sourceMappingURL=summaryUtils.d.
|
|
143
|
+
//# sourceMappingURL=summaryUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summaryUtils.d.ts","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AAStF,OAAO,EACN,KAAK,EACL,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EAGZ,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACN,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAgBnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAelD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,MAAM,CAEpE;AAyBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAIpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC/B,OAAO,EAAE,qBAAqB,EAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,UAAU,GAC1B,IAAI,CAQN;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAC1C,OAAO,EAAE,qBAAqB,EAC9B,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,gBAAgB,GAC/B,IAAI,CAGN;AAED;;GAEG;AACH,qBAAa,kBAAmB,YAAW,qBAAqB;IAC/D,OAAO,CAAC,iBAAiB,CAAa;IAEtC,IAAW,OAAO,IAAI,YAAY,CAKjC;IAED,IAAW,KAAK,IAAI,QAAQ,CAAC,aAAa,CAAC,CAE1C;;IAOD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IACrE,OAAO,CAAC,YAAY,CAAgB;IAE7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAexD,SAAS,CACf,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,IAAI,GAAG,WAAW,CAAC,UAAU,EACxE,MAAM,EAAE,MAAM,GACZ,IAAI;IASA,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,GAAG,IAAI;IAKlE,aAAa,CAAC,EAAE,EAAE,MAAM;IAIxB,cAAc,IAAI,qBAAqB;CAG9C;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC5C,QAAQ,EAAE,KAAK,EACf,QAAQ,GAAE,OAAe,GACvB,qBAAqB,CAqCvB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,GAAE,OAAe,GAAG,gBAAgB,CAgBjG;AAED;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAC/C,QAAQ,EAAE,6BAA6B,GACrC,qBAAqB,CA4BvB;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,YAAY,GAAG,KAAK,CAwC1E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACzC,QAAQ,EAAE,KAAK,GAAG,IAAI,EACtB,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAChE,OAAO,CAqBT;AAED;;GAEG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACzD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqD;IAE/E;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,8BAA8B,GAAG,IAAI;IAIlF;;OAEG;IACH,WAAW,CACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,GACpD,IAAI;IAOP;;OAEG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,8BAA8B;IAIrE;;OAEG;IACH,SAAS,IAAI,MAAM;CAOnB;AAoBD;;;GAGG;AACH,qBAAa,aAAc,YAAW,sBAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqC;IAChE,IAAW,OAAO,IAAI;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAM/C;IAEM,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE;IAInD;;;;;OAKG;IACI,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE;IAevE,QAAQ,CAAC,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE;IAMnD;;OAEG;IACI,kBAAkB,CAAC,aAAa,EAAE,MAAM;IAMxC,SAAS,IAAI,sBAAsB;CAK1C"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { bufferToString, fromBase64ToUtf8, IsoBuffer, Uint8ArrayToString, } from "@fluid-internal/client-utils";
|
|
6
|
-
import { unreachableCase } from "@fluidframework/core-utils";
|
|
6
|
+
import { assert, unreachableCase } from "@fluidframework/core-utils";
|
|
7
7
|
import { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from "@fluidframework/driver-utils";
|
|
8
8
|
import { SummaryType, TreeEntry, } from "@fluidframework/protocol-definitions";
|
|
9
9
|
/**
|
|
@@ -97,13 +97,6 @@ export function addBlobToSummary(summary, key, content) {
|
|
|
97
97
|
summary.stats.blobNodeCount++;
|
|
98
98
|
summary.stats.totalBlobSize += getBlobSize(content);
|
|
99
99
|
}
|
|
100
|
-
/**
|
|
101
|
-
* @internal
|
|
102
|
-
*/
|
|
103
|
-
export function addTreeToSummary(summary, key, summarizeResult) {
|
|
104
|
-
summary.summary.tree[key] = summarizeResult.summary;
|
|
105
|
-
summary.stats = mergeStats(summary.stats, summarizeResult.stats);
|
|
106
|
-
}
|
|
107
100
|
/**
|
|
108
101
|
* @internal
|
|
109
102
|
*/
|
|
@@ -193,6 +186,7 @@ export function convertToSummaryTreeWithStats(snapshot, fullTree = false) {
|
|
|
193
186
|
}
|
|
194
187
|
const summaryTree = builder.getSummaryTree();
|
|
195
188
|
summaryTree.summary.unreferenced = snapshot.unreferenced;
|
|
189
|
+
summaryTree.summary.groupId = snapshot.groupId;
|
|
196
190
|
return summaryTree;
|
|
197
191
|
}
|
|
198
192
|
/**
|
|
@@ -250,6 +244,7 @@ export function convertSnapshotTreeToSummaryTree(snapshot) {
|
|
|
250
244
|
}
|
|
251
245
|
const summaryTree = builder.getSummaryTree();
|
|
252
246
|
summaryTree.summary.unreferenced = snapshot.unreferenced;
|
|
247
|
+
summaryTree.summary.groupId = snapshot.groupId;
|
|
253
248
|
return summaryTree;
|
|
254
249
|
}
|
|
255
250
|
/**
|
|
@@ -292,8 +287,38 @@ export function convertSummaryTreeToITree(summaryTree) {
|
|
|
292
287
|
return {
|
|
293
288
|
entries,
|
|
294
289
|
unreferenced: summaryTree.unreferenced,
|
|
290
|
+
groupId: summaryTree.groupId,
|
|
295
291
|
};
|
|
296
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* Looks in the given attach message snapshot for the .gcdata blob, which would
|
|
295
|
+
* contain the initial GC Data for the node being attached.
|
|
296
|
+
* If it finds it, it notifies GC of all the new outbound routes being added by the attach.
|
|
297
|
+
*
|
|
298
|
+
* @param snapshot - The snapshot from the attach message
|
|
299
|
+
* @param addedGCOutboundRoute - Callback to notify GC of a new outbound route.
|
|
300
|
+
* IMPORTANT: addedGCOutboundRoute's param nodeId is "/" for the attaching node itself, or "/<id>" for its children.
|
|
301
|
+
*
|
|
302
|
+
* @returns true if it found/processed GC Data, false otherwise
|
|
303
|
+
*
|
|
304
|
+
* @internal
|
|
305
|
+
*/
|
|
306
|
+
export function processAttachMessageGCData(snapshot, addedGCOutboundRoute) {
|
|
307
|
+
const gcDataEntry = snapshot?.entries.find((e) => e.path === ".gcdata");
|
|
308
|
+
// Old attach messages won't have GC Data
|
|
309
|
+
// (And REALLY old DataStore Attach messages won't even have a snapshot!)
|
|
310
|
+
if (gcDataEntry === undefined) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
assert(gcDataEntry.type === TreeEntry.Blob && gcDataEntry.value.encoding === "utf-8", 0x8ff /* GC data should be a utf-8-encoded blob */);
|
|
314
|
+
const gcData = JSON.parse(gcDataEntry.value.contents);
|
|
315
|
+
for (const [nodeId, outboundRoutes] of Object.entries(gcData.gcNodes)) {
|
|
316
|
+
outboundRoutes.forEach((toPath) => {
|
|
317
|
+
addedGCOutboundRoute(nodeId, toPath);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
297
322
|
/**
|
|
298
323
|
* @internal
|
|
299
324
|
*/
|
|
@@ -405,4 +430,4 @@ export class GCDataBuilder {
|
|
|
405
430
|
};
|
|
406
431
|
}
|
|
407
432
|
}
|
|
408
|
-
//# sourceMappingURL=summaryUtils.
|
|
433
|
+
//# sourceMappingURL=summaryUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.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 type { TelemetryBaseEventPropertyType } from \"@fluidframework/core-interfaces\";\nimport {\n\tbufferToString,\n\tfromBase64ToUtf8,\n\tIsoBuffer,\n\tUint8ArrayToString,\n} from \"@fluid-internal/client-utils\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils\";\nimport { AttachmentTreeEntry, BlobTreeEntry, TreeTreeEntry } from \"@fluidframework/driver-utils\";\nimport {\n\tITree,\n\tSummaryType,\n\tISummaryTree,\n\tSummaryObject,\n\tISummaryBlob,\n\tTreeEntry,\n\tITreeEntry,\n} from \"@fluidframework/protocol-definitions\";\nimport {\n\tISummaryStats,\n\tISummarizeResult,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIGarbageCollectionData,\n} from \"@fluidframework/runtime-definitions\";\nimport { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions\";\n\n/**\n * Combines summary stats by adding their totals together.\n * Returns empty stats if called without args.\n * @param stats - stats to merge\n * @internal\n */\nexport function mergeStats(...stats: ISummaryStats[]): ISummaryStats {\n\tconst results = {\n\t\ttreeNodeCount: 0,\n\t\tblobNodeCount: 0,\n\t\thandleNodeCount: 0,\n\t\ttotalBlobSize: 0,\n\t\tunreferencedBlobSize: 0,\n\t};\n\tfor (const stat of stats) {\n\t\tresults.treeNodeCount += stat.treeNodeCount;\n\t\tresults.blobNodeCount += stat.blobNodeCount;\n\t\tresults.handleNodeCount += stat.handleNodeCount;\n\t\tresults.totalBlobSize += stat.totalBlobSize;\n\t\tresults.unreferencedBlobSize += stat.unreferencedBlobSize;\n\t}\n\treturn results;\n}\n\n/**\n * @internal\n */\nexport function utf8ByteLength(str: string): number {\n\t// returns the byte length of an utf8 string\n\tlet s = str.length;\n\tfor (let i = str.length - 1; i >= 0; i--) {\n\t\tconst code = str.charCodeAt(i);\n\t\tif (code > 0x7f && code <= 0x7ff) {\n\t\t\ts++;\n\t\t} else if (code > 0x7ff && code <= 0xffff) {\n\t\t\ts += 2;\n\t\t}\n\t\tif (code >= 0xdc00 && code <= 0xdfff) {\n\t\t\ti--; // trail surrogate\n\t\t}\n\t}\n\treturn s;\n}\n\n/**\n * @internal\n */\nexport function getBlobSize(content: ISummaryBlob[\"content\"]): number {\n\treturn typeof content === \"string\" ? utf8ByteLength(content) : content.byteLength;\n}\n\nfunction calculateStatsCore(summaryObject: SummaryObject, stats: ISummaryStats): void {\n\tswitch (summaryObject.type) {\n\t\tcase SummaryType.Tree: {\n\t\t\tstats.treeNodeCount++;\n\t\t\tfor (const value of Object.values(summaryObject.tree)) {\n\t\t\t\tcalculateStatsCore(value, stats);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tcase SummaryType.Handle: {\n\t\t\tstats.handleNodeCount++;\n\t\t\treturn;\n\t\t}\n\t\tcase SummaryType.Blob: {\n\t\t\tstats.blobNodeCount++;\n\t\t\tstats.totalBlobSize += getBlobSize(summaryObject.content);\n\t\t\treturn;\n\t\t}\n\t\tdefault:\n\t\t\treturn;\n\t}\n}\n\n/**\n * @internal\n */\nexport function calculateStats(summary: SummaryObject): ISummaryStats {\n\tconst stats = mergeStats();\n\tcalculateStatsCore(summary, stats);\n\treturn stats;\n}\n\n/**\n * @internal\n */\nexport function addBlobToSummary(\n\tsummary: ISummaryTreeWithStats,\n\tkey: string,\n\tcontent: string | Uint8Array,\n): void {\n\tconst blob: ISummaryBlob = {\n\t\ttype: SummaryType.Blob,\n\t\tcontent,\n\t};\n\tsummary.summary.tree[key] = blob;\n\tsummary.stats.blobNodeCount++;\n\tsummary.stats.totalBlobSize += getBlobSize(content);\n}\n\n/**\n * @internal\n */\nexport function addSummarizeResultToSummary(\n\tsummary: ISummaryTreeWithStats,\n\tkey: string,\n\tsummarizeResult: ISummarizeResult,\n): void {\n\tsummary.summary.tree[key] = summarizeResult.summary;\n\tsummary.stats = mergeStats(summary.stats, summarizeResult.stats);\n}\n\n/**\n * @alpha\n */\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n\tprivate attachmentCounter: number = 0;\n\n\tpublic get summary(): ISummaryTree {\n\t\treturn {\n\t\t\ttype: SummaryType.Tree,\n\t\t\ttree: { ...this.summaryTree },\n\t\t};\n\t}\n\n\tpublic get stats(): Readonly<ISummaryStats> {\n\t\treturn { ...this.summaryStats };\n\t}\n\n\tconstructor() {\n\t\tthis.summaryStats = mergeStats();\n\t\tthis.summaryStats.treeNodeCount++;\n\t}\n\n\tprivate readonly summaryTree: { [path: string]: SummaryObject } = {};\n\tprivate summaryStats: ISummaryStats;\n\n\tpublic addBlob(key: string, content: string | Uint8Array): void {\n\t\t// Prevent cloning by directly referencing underlying private properties\n\t\taddBlobToSummary(\n\t\t\t{\n\t\t\t\tsummary: {\n\t\t\t\t\ttype: SummaryType.Tree,\n\t\t\t\t\ttree: this.summaryTree,\n\t\t\t\t},\n\t\t\t\tstats: this.summaryStats,\n\t\t\t},\n\t\t\tkey,\n\t\t\tcontent,\n\t\t);\n\t}\n\n\tpublic addHandle(\n\t\tkey: string,\n\t\thandleType: SummaryType.Tree | SummaryType.Blob | SummaryType.Attachment,\n\t\thandle: string,\n\t): void {\n\t\tthis.summaryTree[key] = {\n\t\t\ttype: SummaryType.Handle,\n\t\t\thandleType,\n\t\t\thandle,\n\t\t};\n\t\tthis.summaryStats.handleNodeCount++;\n\t}\n\n\tpublic addWithStats(key: string, summarizeResult: ISummarizeResult): void {\n\t\tthis.summaryTree[key] = summarizeResult.summary;\n\t\tthis.summaryStats = mergeStats(this.summaryStats, summarizeResult.stats);\n\t}\n\n\tpublic addAttachment(id: string) {\n\t\tthis.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n\t}\n\n\tpublic getSummaryTree(): ISummaryTreeWithStats {\n\t\treturn { summary: this.summary, stats: this.stats };\n\t}\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n * @alpha\n */\nexport function convertToSummaryTreeWithStats(\n\tsnapshot: ITree,\n\tfullTree: boolean = false,\n): ISummaryTreeWithStats {\n\tconst builder = new SummaryTreeBuilder();\n\tfor (const entry of snapshot.entries) {\n\t\tswitch (entry.type) {\n\t\t\tcase TreeEntry.Blob: {\n\t\t\t\tconst blob = entry.value;\n\t\t\t\tconst content =\n\t\t\t\t\tblob.encoding === \"base64\"\n\t\t\t\t\t\t? IsoBuffer.from(blob.contents, \"base64\")\n\t\t\t\t\t\t: blob.contents;\n\t\t\t\tbuilder.addBlob(entry.path, content);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase TreeEntry.Tree: {\n\t\t\t\tconst subtree = convertToSummaryTree(entry.value, fullTree);\n\t\t\t\tbuilder.addWithStats(entry.path, subtree);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase TreeEntry.Attachment: {\n\t\t\t\tconst id = entry.value.id;\n\t\t\t\tbuilder.addAttachment(id);\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tthrow new Error(\"Unexpected TreeEntry type\");\n\t\t}\n\t}\n\n\tconst summaryTree = builder.getSummaryTree();\n\tsummaryTree.summary.unreferenced = snapshot.unreferenced;\n\tsummaryTree.summary.groupId = snapshot.groupId;\n\treturn summaryTree;\n}\n\n/**\n * Converts snapshot ITree to ISummaryTree format and tracks stats.\n * @param snapshot - snapshot in ITree format\n * @param fullTree - true to never use handles, even if id is specified\n * @internal\n */\nexport function convertToSummaryTree(snapshot: ITree, fullTree: boolean = false): ISummarizeResult {\n\t// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n\tif (snapshot.id && !fullTree) {\n\t\tconst stats = mergeStats();\n\t\tstats.handleNodeCount++;\n\t\treturn {\n\t\t\tsummary: {\n\t\t\t\thandle: snapshot.id,\n\t\t\t\thandleType: SummaryType.Tree,\n\t\t\t\ttype: SummaryType.Handle,\n\t\t\t},\n\t\t\tstats,\n\t\t};\n\t} else {\n\t\treturn convertToSummaryTreeWithStats(snapshot, fullTree);\n\t}\n}\n\n/**\n * Converts ISnapshotTree to ISummaryTree format and tracks stats. This snapshot tree was\n * was taken by serialize api in detached container.\n * @param snapshot - snapshot in ISnapshotTree format\n * @internal\n */\nexport function convertSnapshotTreeToSummaryTree(\n\tsnapshot: ISnapshotTreeWithBlobContents,\n): ISummaryTreeWithStats {\n\tconst builder = new SummaryTreeBuilder();\n\tfor (const [path, id] of Object.entries(snapshot.blobs)) {\n\t\tlet decoded: string | undefined;\n\t\tif (snapshot.blobsContents !== undefined) {\n\t\t\tconst content: ArrayBufferLike = snapshot.blobsContents[id];\n\t\t\tif (content !== undefined) {\n\t\t\t\tdecoded = bufferToString(content, \"utf-8\");\n\t\t\t}\n\t\t\t// 0.44 back-compat We still put contents in same blob for back-compat so need to add blob\n\t\t\t// only for blobPath -> blobId mapping and not for blobId -> blob value contents.\n\t\t} else if (snapshot.blobs[id] !== undefined) {\n\t\t\tdecoded = fromBase64ToUtf8(snapshot.blobs[id]);\n\t\t}\n\t\tif (decoded !== undefined) {\n\t\t\tbuilder.addBlob(path, decoded);\n\t\t}\n\t}\n\n\tfor (const [key, tree] of Object.entries(snapshot.trees)) {\n\t\tconst subtree = convertSnapshotTreeToSummaryTree(tree);\n\t\tbuilder.addWithStats(key, subtree);\n\t}\n\n\tconst summaryTree = builder.getSummaryTree();\n\tsummaryTree.summary.unreferenced = snapshot.unreferenced;\n\tsummaryTree.summary.groupId = snapshot.groupId;\n\treturn summaryTree;\n}\n\n/**\n * Converts ISummaryTree to ITree format. This is needed for back-compat while we get rid of snapshot.\n * @param summaryTree - summary tree in ISummaryTree format\n * @internal\n */\nexport function convertSummaryTreeToITree(summaryTree: ISummaryTree): ITree {\n\tconst entries: ITreeEntry[] = [];\n\tfor (const [key, value] of Object.entries(summaryTree.tree)) {\n\t\tswitch (value.type) {\n\t\t\tcase SummaryType.Blob: {\n\t\t\t\tlet parsedContent: string;\n\t\t\t\tlet encoding: \"utf-8\" | \"base64\" = \"utf-8\";\n\t\t\t\tif (typeof value.content === \"string\") {\n\t\t\t\t\tparsedContent = value.content;\n\t\t\t\t} else {\n\t\t\t\t\tparsedContent = Uint8ArrayToString(value.content, \"base64\");\n\t\t\t\t\tencoding = \"base64\";\n\t\t\t\t}\n\t\t\t\tentries.push(new BlobTreeEntry(key, parsedContent, encoding));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase SummaryType.Tree: {\n\t\t\t\tentries.push(new TreeTreeEntry(key, convertSummaryTreeToITree(value)));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase SummaryType.Attachment: {\n\t\t\t\tentries.push(new AttachmentTreeEntry(key, value.id));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase SummaryType.Handle: {\n\t\t\t\tthrow new Error(\"Should not have Handle type in summary tree\");\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tunreachableCase(value, \"Unexpected summary tree type\");\n\t\t}\n\t}\n\treturn {\n\t\tentries,\n\t\tunreferenced: summaryTree.unreferenced,\n\t\tgroupId: summaryTree.groupId,\n\t};\n}\n\n/**\n * Looks in the given attach message snapshot for the .gcdata blob, which would\n * contain the initial GC Data for the node being attached.\n * If it finds it, it notifies GC of all the new outbound routes being added by the attach.\n *\n * @param snapshot - The snapshot from the attach message\n * @param addedGCOutboundRoute - Callback to notify GC of a new outbound route.\n * IMPORTANT: addedGCOutboundRoute's param nodeId is \"/\" for the attaching node itself, or \"/<id>\" for its children.\n *\n * @returns true if it found/processed GC Data, false otherwise\n *\n * @internal\n */\nexport function processAttachMessageGCData(\n\tsnapshot: ITree | null,\n\taddedGCOutboundRoute: (fromNodeId: string, toPath: string) => void,\n): boolean {\n\tconst gcDataEntry = snapshot?.entries.find((e) => e.path === \".gcdata\");\n\n\t// Old attach messages won't have GC Data\n\t// (And REALLY old DataStore Attach messages won't even have a snapshot!)\n\tif (gcDataEntry === undefined) {\n\t\treturn false;\n\t}\n\n\tassert(\n\t\tgcDataEntry.type === TreeEntry.Blob && gcDataEntry.value.encoding === \"utf-8\",\n\t\t0x8ff /* GC data should be a utf-8-encoded blob */,\n\t);\n\n\tconst gcData = JSON.parse(gcDataEntry.value.contents) as IGarbageCollectionData;\n\tfor (const [nodeId, outboundRoutes] of Object.entries(gcData.gcNodes)) {\n\t\toutboundRoutes.forEach((toPath) => {\n\t\t\taddedGCOutboundRoute(nodeId, toPath);\n\t\t});\n\t}\n\treturn true;\n}\n\n/**\n * @internal\n */\nexport class TelemetryContext implements ITelemetryContext {\n\tprivate readonly telemetry = new Map<string, TelemetryBaseEventPropertyType>();\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.set}\n\t */\n\tset(prefix: string, property: string, value: TelemetryBaseEventPropertyType): void {\n\t\tthis.telemetry.set(`${prefix}${property}`, value);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.setMultiple}\n\t */\n\tsetMultiple(\n\t\tprefix: string,\n\t\tproperty: string,\n\t\tvalues: Record<string, TelemetryBaseEventPropertyType>,\n\t): void {\n\t\t// Set the values individually so that they are logged as a flat list along with other properties.\n\t\tfor (const key of Object.keys(values)) {\n\t\t\tthis.set(prefix, `${property}_${key}`, values[key]);\n\t\t}\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.get}\n\t */\n\tget(prefix: string, property: string): TelemetryBaseEventPropertyType {\n\t\treturn this.telemetry.get(`${prefix}${property}`);\n\t}\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.serialize}\n\t */\n\tserialize(): string {\n\t\tconst jsonObject = {};\n\t\tthis.telemetry.forEach((value, key) => {\n\t\t\tjsonObject[key] = value;\n\t\t});\n\t\treturn JSON.stringify(jsonObject);\n\t}\n}\n\n/**\n * Trims the leading slashes from the given string.\n * @param str - A string that may contain leading slashes.\n * @returns A new string without leading slashes.\n */\nfunction trimLeadingSlashes(str: string) {\n\treturn str.replace(/^\\/+/g, \"\");\n}\n\n/**\n * Trims the trailing slashes from the given string.\n * @param str - A string that may contain trailing slashes.\n * @returns A new string without trailing slashes.\n */\nfunction trimTrailingSlashes(str: string) {\n\treturn str.replace(/\\/+$/g, \"\");\n}\n\n/**\n * Helper class to build the garbage collection data of a node by combining the data from multiple nodes.\n * @internal\n */\nexport class GCDataBuilder implements IGarbageCollectionData {\n\tprivate readonly gcNodesSet: { [id: string]: Set<string> } = {};\n\tpublic get gcNodes(): { [id: string]: string[] } {\n\t\tconst gcNodes = {};\n\t\tfor (const [nodeId, outboundRoutes] of Object.entries(this.gcNodesSet)) {\n\t\t\tgcNodes[nodeId] = [...outboundRoutes];\n\t\t}\n\t\treturn gcNodes;\n\t}\n\n\tpublic addNode(id: string, outboundRoutes: string[]) {\n\t\tthis.gcNodesSet[id] = new Set(outboundRoutes);\n\t}\n\n\t/**\n\t * Adds the given GC nodes. It does the following:\n\t * - Normalizes the ids of the given nodes.\n\t * - Prefixes the given `prefixId` to the given nodes' ids.\n\t * - Adds the outbound routes of the nodes against the normalized and prefixed id.\n\t */\n\tpublic prefixAndAddNodes(prefixId: string, gcNodes: { [id: string]: string[] }) {\n\t\tfor (const [id, outboundRoutes] of Object.entries(gcNodes)) {\n\t\t\t// Remove any leading slashes from the id.\n\t\t\tlet normalizedId = trimLeadingSlashes(id);\n\t\t\t// Prefix the given id to the normalized id.\n\t\t\tnormalizedId = `/${prefixId}/${normalizedId}`;\n\t\t\t// Remove any trailing slashes from the normalized id. Note that the trailing slashes are removed after\n\t\t\t// adding the prefix for handling the special case where id is \"/\".\n\t\t\tnormalizedId = trimTrailingSlashes(normalizedId);\n\n\t\t\t// Add the outbound routes against the normalized and prefixed id without duplicates.\n\t\t\tthis.gcNodesSet[normalizedId] = new Set(outboundRoutes);\n\t\t}\n\t}\n\n\tpublic addNodes(gcNodes: { [id: string]: string[] }) {\n\t\tfor (const [id, outboundRoutes] of Object.entries(gcNodes)) {\n\t\t\tthis.gcNodesSet[id] = new Set(outboundRoutes);\n\t\t}\n\t}\n\n\t/**\n\t * Adds the given outbound route to the outbound routes of all GC nodes.\n\t */\n\tpublic addRouteToAllNodes(outboundRoute: string) {\n\t\tfor (const outboundRoutes of Object.values(this.gcNodesSet)) {\n\t\t\toutboundRoutes.add(outboundRoute);\n\t\t}\n\t}\n\n\tpublic getGCData(): IGarbageCollectionData {\n\t\treturn {\n\t\t\tgcNodes: this.gcNodes,\n\t\t};\n\t}\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { strict as assert } from "assert";
|
|
6
|
+
import { createResponseError, exceptionToResponse, responseToException, } from "../dataStoreHelpers.js";
|
|
7
|
+
describe("createResponseError", () => {
|
|
8
|
+
it("Strip URL query param ", () => {
|
|
9
|
+
const response = createResponseError(400, "SomeValue", { url: "http://foo.com?a=b" });
|
|
10
|
+
assert.strictEqual(response.value, "SomeValue: http://foo.com");
|
|
11
|
+
});
|
|
12
|
+
it("request / response / error handling ", () => {
|
|
13
|
+
const request = { url: "/foo/bar?something" };
|
|
14
|
+
const response = createResponseError(401, "some value", request);
|
|
15
|
+
const value = "some value: /foo/bar";
|
|
16
|
+
assert.strict.equal(response.status, 401, "status code");
|
|
17
|
+
assert.strict.equal(response.value, value, "value");
|
|
18
|
+
const stack = response.stack;
|
|
19
|
+
assert.strict.notEqual(stack, undefined, "stack");
|
|
20
|
+
const exception = responseToException(response, request);
|
|
21
|
+
assert.strict.equal(exception.message, value, "value2");
|
|
22
|
+
assert.strict.equal(exception.stack, stack, "stack2");
|
|
23
|
+
const response2 = exceptionToResponse(exception);
|
|
24
|
+
assert.strict.equal(response2.status, 401, "status code3");
|
|
25
|
+
assert.strict.equal(response2.value, value, "value3");
|
|
26
|
+
assert.strict.equal(response.stack, stack, "stack3");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=dataStoreHelpers.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataStoreHelpers.spec.js","sourceRoot":"","sources":["../../src/test/dataStoreHelpers.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,GACnB,MAAM,wBAAwB,CAAC;AAEhC,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,CAAC,CAAC;QACtF,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,oBAAoB,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QACjE,MAAM,KAAK,GAAG,sBAAsB,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAElD,MAAM,SAAS,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAEtD,MAAM,SAAS,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,cAAc,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QACtD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"assert\";\nimport {\n\tcreateResponseError,\n\texceptionToResponse,\n\tresponseToException,\n} from \"../dataStoreHelpers.js\";\n\ndescribe(\"createResponseError\", () => {\n\tit(\"Strip URL query param \", () => {\n\t\tconst response = createResponseError(400, \"SomeValue\", { url: \"http://foo.com?a=b\" });\n\t\tassert.strictEqual(response.value, \"SomeValue: http://foo.com\");\n\t});\n\n\tit(\"request / response / error handling \", () => {\n\t\tconst request = { url: \"/foo/bar?something\" };\n\t\tconst response = createResponseError(401, \"some value\", request);\n\t\tconst value = \"some value: /foo/bar\";\n\t\tassert.strict.equal(response.status, 401, \"status code\");\n\t\tassert.strict.equal(response.value, value, \"value\");\n\t\tconst stack = response.stack;\n\t\tassert.strict.notEqual(stack, undefined, \"stack\");\n\n\t\tconst exception = responseToException(response, request);\n\t\tassert.strict.equal(exception.message, value, \"value2\");\n\t\tassert.strict.equal(exception.stack, stack, \"stack2\");\n\n\t\tconst response2 = exceptionToResponse(exception);\n\t\tassert.strict.equal(response2.status, 401, \"status code3\");\n\t\tassert.strict.equal(response2.value, value, \"value3\");\n\t\tassert.strict.equal(response.stack, stack, \"stack3\");\n\t});\n});\n"]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import { strict as assert } from "assert";
|
|
6
|
+
import { RequestParser } from "../requestParser.js";
|
|
7
|
+
describe("RequestParser", () => {
|
|
8
|
+
describe(".getPathParts", () => {
|
|
9
|
+
it("Parse Data Store Id", () => {
|
|
10
|
+
const url = "dataStoreId";
|
|
11
|
+
const pathParts = RequestParser.getPathParts(url);
|
|
12
|
+
assert.strictEqual(pathParts.length, 1);
|
|
13
|
+
assert.strictEqual(pathParts[0], "dataStoreId");
|
|
14
|
+
});
|
|
15
|
+
it("Parse Data Store Id with /", () => {
|
|
16
|
+
const url = "/dataStoreId/";
|
|
17
|
+
const pathParts = RequestParser.getPathParts(url);
|
|
18
|
+
assert.strictEqual(pathParts.length, 1);
|
|
19
|
+
assert.strictEqual(pathParts[0], "dataStoreId");
|
|
20
|
+
});
|
|
21
|
+
it("Parse Data Store Id with query", () => {
|
|
22
|
+
const url = "/dataStoreId/?foo=bar";
|
|
23
|
+
const pathParts = RequestParser.getPathParts(url);
|
|
24
|
+
assert.strictEqual(pathParts.length, 1);
|
|
25
|
+
assert.strictEqual(pathParts[0], "dataStoreId");
|
|
26
|
+
});
|
|
27
|
+
it("Parse Data Store Id with sub route with query", () => {
|
|
28
|
+
const url = "/dataStoreId//some/route?foo=bar";
|
|
29
|
+
const pathParts = RequestParser.getPathParts(url);
|
|
30
|
+
assert.strictEqual(pathParts.length, 3);
|
|
31
|
+
assert.strictEqual(pathParts[0], "dataStoreId");
|
|
32
|
+
assert.strictEqual(pathParts[1], "some");
|
|
33
|
+
assert.strictEqual(pathParts[2], "route");
|
|
34
|
+
});
|
|
35
|
+
it("Parse encoded Data Store Id", () => {
|
|
36
|
+
const url = "data%20store%20Id";
|
|
37
|
+
const pathParts = RequestParser.getPathParts(url);
|
|
38
|
+
assert.strictEqual(pathParts.length, 1);
|
|
39
|
+
assert.strictEqual(pathParts[0], "data store Id");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe(".createSubRequest with special characters", () => {
|
|
43
|
+
let requestParser;
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
requestParser = RequestParser.create({ url: "//dataStoreId!@//some!@//route!@//" });
|
|
46
|
+
});
|
|
47
|
+
it("Create request from part 0", () => {
|
|
48
|
+
assert.strictEqual(requestParser.createSubRequest(0).url, "/dataStoreId!@/some!@/route!@");
|
|
49
|
+
});
|
|
50
|
+
it("Create request from part 1", () => {
|
|
51
|
+
assert.strictEqual(requestParser.createSubRequest(1).url, "/some!@/route!@");
|
|
52
|
+
});
|
|
53
|
+
it("Create request from part 2", () => {
|
|
54
|
+
assert.strictEqual(requestParser.createSubRequest(2).url, "/route!@");
|
|
55
|
+
});
|
|
56
|
+
it("Create request from parts length ", () => {
|
|
57
|
+
assert.strictEqual(requestParser.createSubRequest(3).url, "/");
|
|
58
|
+
});
|
|
59
|
+
it("Create request from invalid part ", () => {
|
|
60
|
+
assert.throws(() => requestParser.createSubRequest(4));
|
|
61
|
+
assert.throws(() => requestParser.createSubRequest(-1));
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe(".createSubRequest with special urls", () => {
|
|
65
|
+
it("Create request for `/`", () => {
|
|
66
|
+
const testRequestParser = RequestParser.create({ url: "/" });
|
|
67
|
+
assert.strictEqual(testRequestParser.createSubRequest(0).url, "/");
|
|
68
|
+
assert.throws(() => testRequestParser.createSubRequest(1));
|
|
69
|
+
assert.throws(() => testRequestParser.createSubRequest(-1));
|
|
70
|
+
});
|
|
71
|
+
it("Create request from empty string", () => {
|
|
72
|
+
const testRequestParser = RequestParser.create({ url: "" });
|
|
73
|
+
assert.strictEqual(testRequestParser.createSubRequest(0).url, "/");
|
|
74
|
+
assert.throws(() => testRequestParser.createSubRequest(1));
|
|
75
|
+
assert.throws(() => testRequestParser.createSubRequest(-1));
|
|
76
|
+
});
|
|
77
|
+
it("Create request for just query params", () => {
|
|
78
|
+
const testRequestParser = RequestParser.create({ url: "/?query" });
|
|
79
|
+
assert.strictEqual(testRequestParser.createSubRequest(0).url, "/?query");
|
|
80
|
+
assert.throws(() => testRequestParser.createSubRequest(1));
|
|
81
|
+
assert.throws(() => testRequestParser.createSubRequest(-1));
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
const testSubRequest = function (uri) {
|
|
85
|
+
describe(".createSubRequest with query params", () => {
|
|
86
|
+
let requestParser2;
|
|
87
|
+
beforeEach(() => {
|
|
88
|
+
requestParser2 = RequestParser.create({ url: uri });
|
|
89
|
+
});
|
|
90
|
+
it("Create request from part 0", () => {
|
|
91
|
+
assert.strictEqual(requestParser2.createSubRequest(0).url, "/dataStoreId/some/route/?query1=1&query2=2");
|
|
92
|
+
});
|
|
93
|
+
it("Create request from part 1", () => {
|
|
94
|
+
assert.strictEqual(requestParser2.createSubRequest(1).url, "/some/route/?query1=1&query2=2");
|
|
95
|
+
});
|
|
96
|
+
it("Create request from part 2", () => {
|
|
97
|
+
assert.strictEqual(requestParser2.createSubRequest(2).url, "/route/?query1=1&query2=2");
|
|
98
|
+
});
|
|
99
|
+
it("Create request from parts length", () => {
|
|
100
|
+
assert.strictEqual(requestParser2.createSubRequest(3).url, "/?query1=1&query2=2");
|
|
101
|
+
});
|
|
102
|
+
it("Create request from invalid part ", () => {
|
|
103
|
+
assert.throws(() => requestParser2.createSubRequest(4));
|
|
104
|
+
assert.throws(() => requestParser2.createSubRequest(-1));
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
testSubRequest("/dataStoreId/some/route/?query1=1&query2=2");
|
|
109
|
+
testSubRequest("dataStoreId/some/route/?query1=1&query2=2");
|
|
110
|
+
});
|
|
111
|
+
//# sourceMappingURL=requestParser.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requestParser.spec.js","sourceRoot":"","sources":["../../src/test/requestParser.spec.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 { strict as assert } from \"assert\";\nimport { RequestParser } from \"../requestParser.js\";\n\ndescribe(\"RequestParser\", () => {\n\tdescribe(\".getPathParts\", () => {\n\t\tit(\"Parse Data Store Id\", () => {\n\t\t\tconst url = \"dataStoreId\";\n\t\t\tconst pathParts = RequestParser.getPathParts(url);\n\t\t\tassert.strictEqual(pathParts.length, 1);\n\t\t\tassert.strictEqual(pathParts[0], \"dataStoreId\");\n\t\t});\n\t\tit(\"Parse Data Store Id with /\", () => {\n\t\t\tconst url = \"/dataStoreId/\";\n\t\t\tconst pathParts = RequestParser.getPathParts(url);\n\t\t\tassert.strictEqual(pathParts.length, 1);\n\t\t\tassert.strictEqual(pathParts[0], \"dataStoreId\");\n\t\t});\n\t\tit(\"Parse Data Store Id with query\", () => {\n\t\t\tconst url = \"/dataStoreId/?foo=bar\";\n\t\t\tconst pathParts = RequestParser.getPathParts(url);\n\t\t\tassert.strictEqual(pathParts.length, 1);\n\t\t\tassert.strictEqual(pathParts[0], \"dataStoreId\");\n\t\t});\n\t\tit(\"Parse Data Store Id with sub route with query\", () => {\n\t\t\tconst url = \"/dataStoreId//some/route?foo=bar\";\n\t\t\tconst pathParts = RequestParser.getPathParts(url);\n\t\t\tassert.strictEqual(pathParts.length, 3);\n\t\t\tassert.strictEqual(pathParts[0], \"dataStoreId\");\n\t\t\tassert.strictEqual(pathParts[1], \"some\");\n\t\t\tassert.strictEqual(pathParts[2], \"route\");\n\t\t});\n\t\tit(\"Parse encoded Data Store Id\", () => {\n\t\t\tconst url = \"data%20store%20Id\";\n\t\t\tconst pathParts = RequestParser.getPathParts(url);\n\t\t\tassert.strictEqual(pathParts.length, 1);\n\t\t\tassert.strictEqual(pathParts[0], \"data store Id\");\n\t\t});\n\t});\n\tdescribe(\".createSubRequest with special characters\", () => {\n\t\tlet requestParser: RequestParser;\n\t\tbeforeEach(() => {\n\t\t\trequestParser = RequestParser.create({ url: \"//dataStoreId!@//some!@//route!@//\" });\n\t\t});\n\t\tit(\"Create request from part 0\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\trequestParser.createSubRequest(0).url,\n\t\t\t\t\"/dataStoreId!@/some!@/route!@\",\n\t\t\t);\n\t\t});\n\t\tit(\"Create request from part 1\", () => {\n\t\t\tassert.strictEqual(requestParser.createSubRequest(1).url, \"/some!@/route!@\");\n\t\t});\n\t\tit(\"Create request from part 2\", () => {\n\t\t\tassert.strictEqual(requestParser.createSubRequest(2).url, \"/route!@\");\n\t\t});\n\t\tit(\"Create request from parts length \", () => {\n\t\t\tassert.strictEqual(requestParser.createSubRequest(3).url, \"/\");\n\t\t});\n\t\tit(\"Create request from invalid part \", () => {\n\t\t\tassert.throws(() => requestParser.createSubRequest(4));\n\t\t\tassert.throws(() => requestParser.createSubRequest(-1));\n\t\t});\n\t});\n\n\tdescribe(\".createSubRequest with special urls\", () => {\n\t\tit(\"Create request for `/`\", () => {\n\t\t\tconst testRequestParser = RequestParser.create({ url: \"/\" });\n\t\t\tassert.strictEqual(testRequestParser.createSubRequest(0).url, \"/\");\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(1));\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(-1));\n\t\t});\n\t\tit(\"Create request from empty string\", () => {\n\t\t\tconst testRequestParser = RequestParser.create({ url: \"\" });\n\t\t\tassert.strictEqual(testRequestParser.createSubRequest(0).url, \"/\");\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(1));\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(-1));\n\t\t});\n\t\tit(\"Create request for just query params\", () => {\n\t\t\tconst testRequestParser = RequestParser.create({ url: \"/?query\" });\n\t\t\tassert.strictEqual(testRequestParser.createSubRequest(0).url, \"/?query\");\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(1));\n\t\t\tassert.throws(() => testRequestParser.createSubRequest(-1));\n\t\t});\n\t});\n\n\tconst testSubRequest = function (uri: string) {\n\t\tdescribe(\".createSubRequest with query params\", () => {\n\t\t\tlet requestParser2: RequestParser;\n\t\t\tbeforeEach(() => {\n\t\t\t\trequestParser2 = RequestParser.create({ url: uri });\n\t\t\t});\n\t\t\tit(\"Create request from part 0\", () => {\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\trequestParser2.createSubRequest(0).url,\n\t\t\t\t\t\"/dataStoreId/some/route/?query1=1&query2=2\",\n\t\t\t\t);\n\t\t\t});\n\t\t\tit(\"Create request from part 1\", () => {\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\trequestParser2.createSubRequest(1).url,\n\t\t\t\t\t\"/some/route/?query1=1&query2=2\",\n\t\t\t\t);\n\t\t\t});\n\t\t\tit(\"Create request from part 2\", () => {\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\trequestParser2.createSubRequest(2).url,\n\t\t\t\t\t\"/route/?query1=1&query2=2\",\n\t\t\t\t);\n\t\t\t});\n\t\t\tit(\"Create request from parts length\", () => {\n\t\t\t\tassert.strictEqual(requestParser2.createSubRequest(3).url, \"/?query1=1&query2=2\");\n\t\t\t});\n\t\t\tit(\"Create request from invalid part \", () => {\n\t\t\t\tassert.throws(() => requestParser2.createSubRequest(4));\n\t\t\t\tassert.throws(() => requestParser2.createSubRequest(-1));\n\t\t\t});\n\t\t});\n\t};\n\ttestSubRequest(\"/dataStoreId/some/route/?query1=1&query2=2\");\n\ttestSubRequest(\"dataStoreId/some/route/?query1=1&query2=2\");\n});\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
import Sinon from "sinon";
|
|
6
|
+
import { RuntimeFactoryHelper } from "../runtimeFactoryHelper.js";
|
|
7
|
+
class TestRuntimeFactoryHelper extends RuntimeFactoryHelper {
|
|
8
|
+
constructor(runtime) {
|
|
9
|
+
super();
|
|
10
|
+
this.runtime = runtime;
|
|
11
|
+
}
|
|
12
|
+
async preInitialize(_context, _existing) {
|
|
13
|
+
return this.runtime;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
describe("RuntimeFactoryHelper", () => {
|
|
17
|
+
const sandbox = Sinon.createSandbox();
|
|
18
|
+
const context = {};
|
|
19
|
+
const runtime = {};
|
|
20
|
+
let helper;
|
|
21
|
+
let unit;
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
helper = new TestRuntimeFactoryHelper(runtime);
|
|
24
|
+
unit = sandbox.mock(helper);
|
|
25
|
+
unit.expects("preInitialize").once();
|
|
26
|
+
unit.expects("hasInitialized").once();
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
sandbox.restore();
|
|
30
|
+
});
|
|
31
|
+
it("Instantiate when existing flag is `true`", async () => {
|
|
32
|
+
unit.expects("instantiateFirstTime").never();
|
|
33
|
+
unit.expects("instantiateFromExisting").once();
|
|
34
|
+
await helper.instantiateRuntime(context, /* existing */ true);
|
|
35
|
+
unit.verify();
|
|
36
|
+
});
|
|
37
|
+
it("Instantiate when existing flag is `false`", async () => {
|
|
38
|
+
unit.expects("instantiateFirstTime").once();
|
|
39
|
+
unit.expects("instantiateFromExisting").never();
|
|
40
|
+
await helper.instantiateRuntime(context, /* existing */ false);
|
|
41
|
+
unit.verify();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=runtimeFactoryHelper.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtimeFactoryHelper.spec.js","sourceRoot":"","sources":["../../src/test/runtimeFactoryHelper.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAElE,MAAM,wBAAyB,SAAQ,oBAAoB;IAC1D,YAA6B,OAAqC;QACjE,KAAK,EAAE,CAAC;QADoB,YAAO,GAAP,OAAO,CAA8B;IAElE,CAAC;IAEM,KAAK,CAAC,aAAa,CACzB,QAA2B,EAC3B,SAAkB;QAElB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;CACD;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACrC,MAAM,OAAO,GAAuB,KAAK,CAAC,aAAa,EAAE,CAAC;IAC1D,MAAM,OAAO,GAA+B,EAAE,CAAC;IAC/C,MAAM,OAAO,GAA0C,EAAE,CAAC;IAC1D,IAAI,MAAgC,CAAC;IACrC,IAAI,IAAqB,CAAC;IAE1B,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,IAAI,wBAAwB,CAAC,OAAuC,CAAC,CAAC;QAC/E,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACd,OAAO,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACzD,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,MAAM,CAAC,kBAAkB,CAAC,OAA4B,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;QAEnF,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QAC1D,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;QAChD,MAAM,MAAM,CAAC,kBAAkB,CAAC,OAA4B,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { IContainerContext, IRuntime } from \"@fluidframework/container-definitions\";\nimport { IContainerRuntime } from \"@fluidframework/container-runtime-definitions\";\nimport Sinon from \"sinon\";\nimport { RuntimeFactoryHelper } from \"../runtimeFactoryHelper.js\";\n\nclass TestRuntimeFactoryHelper extends RuntimeFactoryHelper {\n\tconstructor(private readonly runtime: IRuntime & IContainerRuntime) {\n\t\tsuper();\n\t}\n\n\tpublic async preInitialize(\n\t\t_context: IContainerContext,\n\t\t_existing: boolean,\n\t): Promise<IRuntime & IContainerRuntime> {\n\t\treturn this.runtime;\n\t}\n}\n\ndescribe(\"RuntimeFactoryHelper\", () => {\n\tconst sandbox: Sinon.SinonSandbox = Sinon.createSandbox();\n\tconst context: Partial<IContainerContext> = {};\n\tconst runtime: Partial<IRuntime & IContainerRuntime> = {};\n\tlet helper: TestRuntimeFactoryHelper;\n\tlet unit: Sinon.SinonMock;\n\n\tbeforeEach(() => {\n\t\thelper = new TestRuntimeFactoryHelper(runtime as IRuntime & IContainerRuntime);\n\t\tunit = sandbox.mock(helper);\n\t\tunit.expects(\"preInitialize\").once();\n\t\tunit.expects(\"hasInitialized\").once();\n\t});\n\n\tafterEach(() => {\n\t\tsandbox.restore();\n\t});\n\n\tit(\"Instantiate when existing flag is `true`\", async () => {\n\t\tunit.expects(\"instantiateFirstTime\").never();\n\t\tunit.expects(\"instantiateFromExisting\").once();\n\t\tawait helper.instantiateRuntime(context as IContainerContext, /* existing */ true);\n\n\t\tunit.verify();\n\t});\n\n\tit(\"Instantiate when existing flag is `false`\", async () => {\n\t\tunit.expects(\"instantiateFirstTime\").once();\n\t\tunit.expects(\"instantiateFromExisting\").never();\n\t\tawait helper.instantiateRuntime(context as IContainerContext, /* existing */ false);\n\n\t\tunit.verify();\n\t});\n});\n"]}
|