@fluidframework/runtime-utils 2.118.0 → 3.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/CHANGELOG.md +34 -4
- package/README.md +53 -50
- package/{api-extractor.json → api-extractor/api-extractor-model.json} +1 -1
- package/dist/compatibilityBase.d.ts +27 -54
- package/dist/compatibilityBase.d.ts.map +1 -1
- package/dist/compatibilityBase.js +49 -74
- package/dist/compatibilityBase.js.map +1 -1
- package/dist/dataStoreHandleContextUtils.js +1 -2
- package/dist/dataStoreHandleContextUtils.js.map +1 -1
- package/dist/dataStoreHelpers.d.ts.map +1 -1
- package/dist/dataStoreHelpers.js +6 -6
- package/dist/dataStoreHelpers.js.map +1 -1
- package/dist/deltaManager.js +2 -3
- package/dist/deltaManager.js.map +1 -1
- package/dist/handles.d.ts +1 -1
- package/dist/handles.d.ts.map +1 -1
- package/dist/handles.js +7 -7
- package/dist/handles.js.map +1 -1
- package/dist/objectstoragepartition.js +2 -0
- package/dist/objectstoragepartition.js.map +1 -1
- package/dist/objectstorageutils.js +2 -3
- package/dist/objectstorageutils.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.d.ts.map +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/remoteFluidObjectHandle.js +5 -1
- package/dist/remoteFluidObjectHandle.js.map +1 -1
- package/dist/requestParser.js +4 -0
- package/dist/requestParser.js.map +1 -1
- package/dist/serviceClientBase.js +14 -6
- package/dist/serviceClientBase.js.map +1 -1
- package/dist/serviceClientUtils.js +6 -4
- package/dist/serviceClientUtils.js.map +1 -1
- package/dist/snapshotUtils.js +1 -2
- package/dist/snapshotUtils.js.map +1 -1
- package/dist/summaryUtils.d.ts.map +1 -1
- package/dist/summaryUtils.js +18 -22
- package/dist/summaryUtils.js.map +1 -1
- package/dist/unpackUsedRoutes.js +1 -2
- package/dist/unpackUsedRoutes.js.map +1 -1
- package/dist/utils.js +3 -3
- package/dist/utils.js.map +1 -1
- package/lib/compatibilityBase.d.ts +27 -54
- package/lib/compatibilityBase.d.ts.map +1 -1
- package/lib/compatibilityBase.js +40 -65
- package/lib/compatibilityBase.js.map +1 -1
- package/lib/dataStoreHelpers.d.ts.map +1 -1
- package/lib/handles.d.ts +1 -1
- package/lib/handles.d.ts.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/legacyAlpha.d.ts +1 -1
- package/lib/objectstoragepartition.js +2 -0
- package/lib/objectstoragepartition.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.d.ts.map +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/remoteFluidObjectHandle.js +5 -1
- package/lib/remoteFluidObjectHandle.js.map +1 -1
- package/lib/requestParser.js +4 -0
- package/lib/requestParser.js.map +1 -1
- package/lib/serviceClientBase.js +12 -4
- package/lib/serviceClientBase.js.map +1 -1
- package/lib/serviceClientUtils.js +2 -0
- package/lib/serviceClientUtils.js.map +1 -1
- package/lib/summaryUtils.d.ts.map +1 -1
- package/lib/summaryUtils.js +6 -10
- package/lib/summaryUtils.js.map +1 -1
- package/package.json +37 -54
- package/src/compatibilityBase.ts +62 -82
- package/src/packageVersion.ts +1 -1
- package/src/summaryUtils.ts +1 -3
- package/tsconfig.json +1 -1
- package/internal.d.ts +0 -11
- package/legacy/alpha.d.ts +0 -11
- package/legacy.d.ts +0 -11
- /package/api-extractor/{api-extractor.current.json → api-extractor-report.current.json} +0 -0
- /package/api-extractor/{api-extractor.legacy.json → api-extractor-report.legacy.json} +0 -0
package/dist/summaryUtils.js.map
CHANGED
|
@@ -1 +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 {\n\tIsoBuffer,\n\tUint8ArrayToString,\n\tbufferToString,\n\tfromBase64ToUtf8,\n} from \"@fluid-internal/client-utils\";\nimport type { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tISummaryBlob,\n\tISummaryTree,\n\tSummaryObject,\n} from \"@fluidframework/driver-definitions\";\nimport { SummaryType } from \"@fluidframework/driver-definitions\";\nimport type { ITree, ITreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport { TreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tAttachmentTreeEntry,\n\tBlobTreeEntry,\n\tTreeTreeEntry,\n} from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryStats,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContextExt,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tcurrentSummarizeStepPrefix,\n\tcurrentSummarizeStepPropertyName,\n\tgcDataBlobKey,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { TelemetryEventPropertyTypeExt } from \"@fluidframework/telemetry-utils/internal\";\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 * Calculates the byte length of an UTF-8 encoded string\n * @param str - The string to calculate the byte length of\n * @returns The byte length of the string\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.codePointAt(i);\n\t\tif (code !== undefined) {\n\t\t\tif (code > 0x7f && code <= 0x7ff) {\n\t\t\t\ts++;\n\t\t\t} else if (code > 0x7ff && code <= 0xffff) {\n\t\t\t\ts += 2;\n\t\t\t}\n\t\t\tif (code >= 0xdc00 && code <= 0xdfff) {\n\t\t\t\ti--; // trail surrogate\n\t\t\t}\n\t\t}\n\t}\n\treturn s;\n}\n\n/**\n * Gets the size of a blob\n * @param content - The content of the blob\n * @returns The size of the blob in bytes\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\t}\n\t}\n}\n\n/**\n * Calculates the stats for a summary object\n * @param summary - The summary object to calculate stats for\n * @returns The calculated stats\n * @internal\n */\nexport function calculateStats(summary: SummaryObject): ISummaryStats {\n\tconst stats = mergeStats();\n\tcalculateStatsCore(summary, stats);\n\treturn stats;\n}\n\n/**\n * Adds a blob to the summary tree\n * @param summary - The summary tree to add the blob to\n * @param key - The key to store the blob at\n * @param content - The content of the blob to be added\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 * Adds a summarize result to the summary tree\n * @param summary - The summary tree to add the summarize result to\n * @param key - The key to store the summarize result at\n * @param summarizeResult - The summarize result to be added\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 * An object who's properties are used to initialize a {@link SummaryTreeBuilder}\n * @legacy @beta\n */\nexport interface SummaryTreeBuilderParams {\n\t/**\n\t * This value will become the {@link @fluidframework/driver-definitions#ISummaryTree.groupId}\n\t * of the {@link @fluidframework/driver-definitions#ISummaryTree} built by the {@link SummaryTreeBuilder}.\n\t */\n\tgroupId?: string;\n}\n/**\n * A helper class for building summary trees.\n * @remarks Uses the builder pattern.\n * @legacy @beta\n */\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n\tprivate attachmentCounter: number = 0;\n\tprivate readonly groupId?: string;\n\n\tpublic get summary(): ISummaryTree {\n\t\tconst summary: ISummaryTree = {\n\t\t\ttype: SummaryType.Tree,\n\t\t\ttree: { ...this.summaryTree },\n\t\t};\n\t\tif (this.groupId !== undefined) {\n\t\t\tsummary.groupId = this.groupId;\n\t\t}\n\t\treturn summary;\n\t}\n\n\tpublic get stats(): Readonly<ISummaryStats> {\n\t\treturn { ...this.summaryStats };\n\t}\n\n\tpublic constructor(params?: { groupId?: string }) {\n\t\tthis.summaryStats = mergeStats();\n\t\tthis.summaryStats.treeNodeCount++;\n\t\tthis.groupId = params?.groupId;\n\t}\n\n\tprivate readonly summaryTree: Record<string, SummaryObject> = {};\n\tprivate summaryStats: ISummaryStats;\n\n\t/**\n\t * Add a blob to the summary tree. This blob will be stored at the given key in the summary tree.\n\t * @param key - The key to store the blob at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * @param content - The content of the blob to be added to the summary tree.\n\t */\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\t/**\n\t * Adds an {@link @fluidframework/driver-definitions#ISummaryHandle} that references a subtree, blob, or attachment in a previous summary.\n\t *\n\t * @param key - The key to store the handle at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * @param handleType - the type of {@link @fluidframework/driver-definitions#SummaryObject} besides a SummaryHandle, i.e. {@link @fluidframework/driver-definitions#SummaryType.Tree}, {@link @fluidframework/driver-definitions#SummaryType.Blob}, {@link @fluidframework/driver-definitions#SummaryType.Attachment}\n\t * @param handle - The path pointing to the part of the previous summary being used to duplicate the data. Use {@link @fluidframework/driver-definitions#ISummaryHandle.handle} to help generate proper handle strings. Should not contain any \"/\" characters.\n\t */\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\t/**\n\t * Adds a child and updates the stats accordingly.\n\t * @param key - The key to store the handle at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * The key should be unique within the current summary tree, and not transform when encodeURIComponent is called.\n\t * @param summarizeResult - Similar to {@link @fluidframework/runtime-definitions#ISummaryTreeWithStats}. The provided summary can be either a {@link @fluidframework/driver-definitions#ISummaryHandle} or {@link @fluidframework/driver-definitions#ISummaryTree}.\n\t */\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\t/**\n\t * Adds an {@link @fluidframework/driver-definitions#ISummaryAttachment} to the summary. This blob needs to already be uploaded to storage.\n\t * @param id - The id of the uploaded attachment to be added to the summary tree.\n\t */\n\tpublic addAttachment(id: string): void {\n\t\tthis.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n\t}\n\n\t/**\n\t * Gives you the in-memory summary tree with stats built by the SummaryTreeBuilder.\n\t *\n\t * @remarks\n\t * Use this once you're done building the summary tree, the stats should automatically be generated.\n\t * @returns The summary tree and stats built by the SummaryTreeBuilder.\n\t */\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 * @legacy @beta\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\" ? IsoBuffer.from(blob.contents, \"base64\") : 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\t}\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(\n\tsnapshot: ITree,\n\tfullTree: boolean = false,\n): 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\t// TODO Why are we non null asserting here?\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst content: ArrayBufferLike = snapshot.blobsContents[id]!;\n\t\t\tif (content !== undefined) {\n\t\t\t\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- External on-disk format is 'utf-8'.\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\t// Non null asserting here because of the undefined check above\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\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\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- external contract uses 'utf-8'.\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\t}\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 | undefined,\n\taddedGCOutboundRoute: (fromNodeId: string, toPath: string) => void,\n): boolean {\n\tconst gcDataEntry = snapshot?.entries.find((e) => e.path === gcDataBlobKey);\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\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- external contract uses 'utf-8'.\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\t// Type assertion is safe as we expect the GC data to conform to IGarbageCollectionData schema\n\tconst gcData = JSON.parse(gcDataEntry.value.contents) as IGarbageCollectionData;\n\tfor (const [nodeId, outboundRoutes] of Object.entries(gcData.gcNodes)) {\n\t\tfor (const toPath of outboundRoutes) {\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, ITelemetryContextExt {\n\tprivate readonly telemetry = new Map<string, TelemetryEventPropertyTypeExt>();\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.set}\n\t */\n\tpublic set(prefix: string, property: string, value: TelemetryEventPropertyTypeExt): 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\tpublic setMultiple(\n\t\tprefix: string,\n\t\tproperty: string,\n\t\tvalues: Record<string, TelemetryEventPropertyTypeExt>,\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 * Get the telemetry data being tracked\n\t * @param prefix - unique prefix to tag this data with (ex: \"fluid:map:\")\n\t * @param property - property name of the telemetry data being tracked (ex: \"DirectoryCount\")\n\t * @returns undefined if item not found\n\t */\n\tpublic get(prefix: string, property: string): TelemetryEventPropertyTypeExt {\n\t\treturn this.telemetry.get(`${prefix}${property}`);\n\t}\n\n\t/**\n\t * Returns a serialized version of all the telemetry data.\n\t * Should be used when logging in telemetry events.\n\t */\n\tpublic serialize(): string {\n\t\tconst jsonObject = {};\n\t\tfor (const [key, value] of this.telemetry.entries()) {\n\t\t\tjsonObject[key] = value;\n\t\t}\n\t\treturn JSON.stringify(jsonObject);\n\t}\n\n\tpublic getCurrentSummarizeStep(): TelemetryEventPropertyTypeExt {\n\t\treturn this.get(currentSummarizeStepPrefix, currentSummarizeStepPropertyName);\n\t}\n\n\tpublic setCurrentSummarizeStep(value: TelemetryEventPropertyTypeExt): void {\n\t\tthis.set(currentSummarizeStepPrefix, currentSummarizeStepPropertyName, value);\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): 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): 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: Record<string, Set<string>> = {};\n\tpublic get gcNodes(): Record<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[]): void {\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: Record<string, string[]>): void {\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: Record<string, string[]>): void {\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): void {\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"]}
|
|
1
|
+
{"version":3,"file":"summaryUtils.js","sourceRoot":"","sources":["../src/summaryUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA4CH,gCAgBC;AAQD,wCAiBC;AAQD,kCAEC;AAgCD,wCAIC;AASD,4CAYC;AASD,kEAOC;AA2HD,sEAuCC;AAQD,oDAmBC;AAQD,4EAkCC;AAOD,8DA2CC;AAeD,gEA2BC;AAzeD,+DAKsC;AAEtC,kEAA8E;AAM9E,2EAAiE;AAEjE,0EAAwE;AACxE,oEAI+C;AAS/C,2EAIsD;AAGtD;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,GAAG,KAAsB;IACnD,MAAM,OAAO,GAAG;QACf,aAAa,EAAE,CAAC;QAChB,aAAa,EAAE,CAAC;QAChB,eAAe,EAAE,CAAC;QAClB,aAAa,EAAE,CAAC;QAChB,oBAAoB,EAAE,CAAC;KACvB,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC;QAC5C,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC;QAC5C,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;QAChD,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC;QAC5C,OAAO,CAAC,oBAAoB,IAAI,IAAI,CAAC,oBAAoB,CAAC;IAC3D,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,GAAW;IACzC,4CAA4C;IAC5C,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IACnB,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;gBAClC,CAAC,EAAE,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBAC3C,CAAC,IAAI,CAAC,CAAC;YACR,CAAC;YACD,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;gBACtC,CAAC,EAAE,CAAC,CAAC,kBAAkB;YACxB,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,CAAC,CAAC;AACV,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,OAAgC;IAC3D,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;AACnF,CAAC;AAED,SAAS,kBAAkB,CAAC,aAA4B,EAAE,KAAoB;IAC7E,QAAQ,aAAa,CAAC,IAAI,EAAE,CAAC;QAC5B,KAAK,gCAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvD,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAClC,CAAC;YACD,OAAO;QACR,CAAC;QACD,KAAK,gCAAW,CAAC,MAAM,CAAC,CAAC,CAAC;YACzB,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,OAAO;QACR,CAAC;QACD,KAAK,gCAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,aAAa,EAAE,CAAC;YACtB,KAAK,CAAC,aAAa,IAAI,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;YAC1D,OAAO;QACR,CAAC;QACD,OAAO,CAAC,CAAC,CAAC;YACT,OAAO;QACR,CAAC;IACF,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,cAAc,CAAC,OAAsB;IACpD,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,gBAAgB,CAC/B,OAA8B,EAC9B,GAAW,EACX,OAA4B;IAE5B,MAAM,IAAI,GAAiB;QAC1B,IAAI,EAAE,gCAAW,CAAC,IAAI;QACtB,OAAO;KACP,CAAC;IACF,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACjC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,aAAa,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AACrD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,2BAA2B,CAC1C,OAA8B,EAC9B,GAAW,EACX,eAAiC;IAEjC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC;IACpD,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAaD;;;;GAIG;AACH,MAAa,kBAAkB;IACtB,iBAAiB,GAAW,CAAC,CAAC;IACrB,OAAO,CAAU;IAElC,IAAW,OAAO;QACjB,MAAM,OAAO,GAAiB;YAC7B,IAAI,EAAE,gCAAW,CAAC,IAAI;YACtB,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE;SAC7B,CAAC;QACF,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAChC,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,IAAW,KAAK;QACf,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;IACjC,CAAC;IAED,YAAmB,MAA6B;QAC/C,IAAI,CAAC,YAAY,GAAG,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC;QAClC,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,OAAO,CAAC;IAChC,CAAC;IAEgB,WAAW,GAAkC,EAAE,CAAC;IACzD,YAAY,CAAgB;IAEpC;;;;OAIG;IACI,OAAO,CAAC,GAAW,EAAE,OAA4B;QACvD,wEAAwE;QACxE,gBAAgB,CACf;YACC,OAAO,EAAE;gBACR,IAAI,EAAE,gCAAW,CAAC,IAAI;gBACtB,IAAI,EAAE,IAAI,CAAC,WAAW;aACtB;YACD,KAAK,EAAE,IAAI,CAAC,YAAY;SACxB,EACD,GAAG,EACH,OAAO,CACP,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACI,SAAS,CACf,GAAW,EACX,UAAwE,EACxE,MAAc;QAEd,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG;YACvB,IAAI,EAAE,gCAAW,CAAC,MAAM;YACxB,UAAU;YACV,MAAM;SACN,CAAC;QACF,IAAI,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACI,YAAY,CAAC,GAAW,EAAE,eAAiC;QACjE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC;QAChD,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,EAAU;QAC9B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,gCAAW,CAAC,UAAU,EAAE,CAAC;IACnF,CAAC;IAED;;;;;;OAMG;IACI,cAAc;QACpB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACrD,CAAC;CACD;AAjGD,gDAiGC;AAED;;;;;GAKG;AACH,SAAgB,6BAA6B,CAC5C,QAAe,EACf,WAAoB,KAAK;IAEzB,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,oBAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;gBACzB,MAAM,OAAO,GACZ,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,wBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACtF,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBACrC,MAAM;YACP,CAAC;YAED,KAAK,oBAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBACrB,MAAM,OAAO,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAC5D,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAE1C,MAAM;YACP,CAAC;YAED,KAAK,oBAAS,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;gBAE1B,MAAM;YACP,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAC7C,WAAW,CAAC,OAAO,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;IACzD,WAAW,CAAC,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC/C,OAAO,WAAW,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CACnC,QAAe,EACf,WAAoB,KAAK;IAEzB,yEAAyE;IACzE,IAAI,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;QACxB,OAAO;YACN,OAAO,EAAE;gBACR,MAAM,EAAE,QAAQ,CAAC,EAAE;gBACnB,UAAU,EAAE,gCAAW,CAAC,IAAI;gBAC5B,IAAI,EAAE,gCAAW,CAAC,MAAM;aACxB;YACD,KAAK;SACL,CAAC;IACH,CAAC;SAAM,CAAC;QACP,OAAO,6BAA6B,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1D,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gCAAgC,CAC/C,QAAuC;IAEvC,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,IAAI,OAA2B,CAAC;QAChC,IAAI,QAAQ,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YAC1C,2CAA2C;YAC3C,oEAAoE;YACpE,MAAM,OAAO,GAAoB,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAE,CAAC;YAC7D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC3B,qKAAqK;gBACrK,wGAAwG;gBACxG,OAAO,GAAG,IAAA,6BAAc,EAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC5C,CAAC;YACD,0FAA0F;YAC1F,iFAAiF;QAClF,CAAC;aAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;YAC7C,OAAO,GAAG,IAAA,+BAAgB,EAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;IACF,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,gCAAgC,CAAC,IAAI,CAAC,CAAC;QACvD,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAC7C,WAAW,CAAC,OAAO,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC;IACzD,WAAW,CAAC,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC/C,OAAO,WAAW,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,WAAyB;IAClE,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,gCAAW,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvB,IAAI,aAAqB,CAAC;gBAC1B,qKAAqK;gBACrK,oGAAoG;gBACpG,IAAI,QAAQ,GAAuB,OAAO,CAAC;gBAC3C,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;oBACvC,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACP,aAAa,GAAG,IAAA,iCAAkB,EAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;oBAC5D,QAAQ,GAAG,QAAQ,CAAC;gBACrB,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,IAAI,wBAAa,CAAC,GAAG,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC;gBAC9D,MAAM;YACP,CAAC;YAED,KAAK,gCAAW,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,IAAI,wBAAa,CAAC,GAAG,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvE,MAAM;YACP,CAAC;YAED,KAAK,gCAAW,CAAC,UAAU,CAAC,CAAC,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,IAAI,8BAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,MAAM;YACP,CAAC;YAED,KAAK,gCAAW,CAAC,MAAM,CAAC,CAAC,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAChE,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACT,IAAA,0BAAe,EAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;YACxD,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO;QACN,OAAO;QACP,YAAY,EAAE,WAAW,CAAC,YAAY;QACtC,OAAO,EAAE,WAAW,CAAC,OAAO;KAC5B,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,0BAA0B,CACzC,QAA2B,EAC3B,oBAAkE;IAElE,MAAM,WAAW,GAAG,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAa,CAAC,CAAC;IAE5E,yCAAyC;IACzC,yEAAyE;IACzE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,IAAA,iBAAM;IACL,qKAAqK;IACrK,qGAAqG;IACrG,WAAW,CAAC,IAAI,KAAK,oBAAS,CAAC,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,EAC7E,KAAK,CAAC,4CAA4C,CAClD,CAAC;IAEF,8FAA8F;IAC9F,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAA2B,CAAC;IAChF,KAAK,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACvE,KAAK,MAAM,MAAM,IAAI,cAAc,EAAE,CAAC;YACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAa,gBAAgB;IACX,SAAS,GAAG,IAAI,GAAG,EAAyC,CAAC;IAE9E;;OAEG;IACI,GAAG,CAAC,MAAc,EAAE,QAAgB,EAAE,KAAoC;QAChF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACI,WAAW,CACjB,MAAc,EACd,QAAgB,EAChB,MAAqD;QAErD,kGAAkG;QAClG,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,QAAQ,IAAI,GAAG,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;IACF,CAAC;IAED;;;;;OAKG;IACI,GAAG,CAAC,MAAc,EAAE,QAAgB;QAC1C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,QAAQ,EAAE,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,MAAM,UAAU,GAAG,EAAE,CAAC;QACtB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;YACrD,UAAU,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzB,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAEM,uBAAuB;QAC7B,OAAO,IAAI,CAAC,GAAG,CAAC,qCAA0B,EAAE,2CAAgC,CAAC,CAAC;IAC/E,CAAC;IAEM,uBAAuB,CAAC,KAAoC;QAClE,IAAI,CAAC,GAAG,CAAC,qCAA0B,EAAE,2CAAgC,EAAE,KAAK,CAAC,CAAC;IAC/E,CAAC;CACD;AArDD,4CAqDC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,GAAW;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,GAAW;IACvC,OAAO,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAa,aAAa;IACR,UAAU,GAAgC,EAAE,CAAC;IAC9D,IAAW,OAAO;QACjB,MAAM,OAAO,GAAG,EAAE,CAAC;QACnB,KAAK,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACxE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,CAAC;QACvC,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,OAAO,CAAC,EAAU,EAAE,cAAwB;QAClD,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;OAKG;IACI,iBAAiB,CAAC,QAAgB,EAAE,OAAiC;QAC3E,KAAK,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,0CAA0C;YAC1C,IAAI,YAAY,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;YAC1C,4CAA4C;YAC5C,YAAY,GAAG,IAAI,QAAQ,IAAI,YAAY,EAAE,CAAC;YAC9C,uGAAuG;YACvG,mEAAmE;YACnE,YAAY,GAAG,mBAAmB,CAAC,YAAY,CAAC,CAAC;YAEjD,qFAAqF;YACrF,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAEM,QAAQ,CAAC,OAAiC;QAChD,KAAK,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;QAC/C,CAAC;IACF,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,aAAqB;QAC9C,KAAK,MAAM,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7D,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IAEM,SAAS;QACf,OAAO;YACN,OAAO,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC;IACH,CAAC;CACD;AAvDD,sCAuDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tIsoBuffer,\n\tUint8ArrayToString,\n\tbufferToString,\n\tfromBase64ToUtf8,\n} from \"@fluid-internal/client-utils\";\nimport type { ISnapshotTreeWithBlobContents } from \"@fluidframework/container-definitions/internal\";\nimport { assert, unreachableCase } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tISummaryBlob,\n\tISummaryTree,\n\tSummaryObject,\n} from \"@fluidframework/driver-definitions\";\nimport { SummaryType } from \"@fluidframework/driver-definitions\";\nimport type { ITree, ITreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport { TreeEntry } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tAttachmentTreeEntry,\n\tBlobTreeEntry,\n\tTreeTreeEntry,\n} from \"@fluidframework/driver-utils/internal\";\nimport type {\n\tISummaryStats,\n\tISummaryTreeWithStats,\n\tITelemetryContext,\n\tIGarbageCollectionData,\n\tISummarizeResult,\n\tITelemetryContextExt,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport {\n\tcurrentSummarizeStepPrefix,\n\tcurrentSummarizeStepPropertyName,\n\tgcDataBlobKey,\n} from \"@fluidframework/runtime-definitions/internal\";\nimport type { TelemetryEventPropertyTypeExt } from \"@fluidframework/telemetry-utils/internal\";\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 * Calculates the byte length of an UTF-8 encoded string\n * @param str - The string to calculate the byte length of\n * @returns The byte length of the string\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.codePointAt(i);\n\t\tif (code !== undefined) {\n\t\t\tif (code > 0x7f && code <= 0x7ff) {\n\t\t\t\ts++;\n\t\t\t} else if (code > 0x7ff && code <= 0xffff) {\n\t\t\t\ts += 2;\n\t\t\t}\n\t\t\tif (code >= 0xdc00 && code <= 0xdfff) {\n\t\t\t\ti--; // trail surrogate\n\t\t\t}\n\t\t}\n\t}\n\treturn s;\n}\n\n/**\n * Gets the size of a blob\n * @param content - The content of the blob\n * @returns The size of the blob in bytes\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\t}\n\t}\n}\n\n/**\n * Calculates the stats for a summary object\n * @param summary - The summary object to calculate stats for\n * @returns The calculated stats\n * @internal\n */\nexport function calculateStats(summary: SummaryObject): ISummaryStats {\n\tconst stats = mergeStats();\n\tcalculateStatsCore(summary, stats);\n\treturn stats;\n}\n\n/**\n * Adds a blob to the summary tree\n * @param summary - The summary tree to add the blob to\n * @param key - The key to store the blob at\n * @param content - The content of the blob to be added\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 * Adds a summarize result to the summary tree\n * @param summary - The summary tree to add the summarize result to\n * @param key - The key to store the summarize result at\n * @param summarizeResult - The summarize result to be added\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 * An object who's properties are used to initialize a {@link SummaryTreeBuilder}\n * @legacy @beta\n */\nexport interface SummaryTreeBuilderParams {\n\t/**\n\t * This value will become the {@link @fluidframework/driver-definitions#ISummaryTree.groupId}\n\t * of the {@link @fluidframework/driver-definitions#ISummaryTree} built by the {@link SummaryTreeBuilder}.\n\t */\n\tgroupId?: string;\n}\n/**\n * A helper class for building summary trees.\n * @remarks Uses the builder pattern.\n * @legacy @beta\n */\nexport class SummaryTreeBuilder implements ISummaryTreeWithStats {\n\tprivate attachmentCounter: number = 0;\n\tprivate readonly groupId?: string;\n\n\tpublic get summary(): ISummaryTree {\n\t\tconst summary: ISummaryTree = {\n\t\t\ttype: SummaryType.Tree,\n\t\t\ttree: { ...this.summaryTree },\n\t\t};\n\t\tif (this.groupId !== undefined) {\n\t\t\tsummary.groupId = this.groupId;\n\t\t}\n\t\treturn summary;\n\t}\n\n\tpublic get stats(): Readonly<ISummaryStats> {\n\t\treturn { ...this.summaryStats };\n\t}\n\n\tpublic constructor(params?: { groupId?: string }) {\n\t\tthis.summaryStats = mergeStats();\n\t\tthis.summaryStats.treeNodeCount++;\n\t\tthis.groupId = params?.groupId;\n\t}\n\n\tprivate readonly summaryTree: Record<string, SummaryObject> = {};\n\tprivate summaryStats: ISummaryStats;\n\n\t/**\n\t * Add a blob to the summary tree. This blob will be stored at the given key in the summary tree.\n\t * @param key - The key to store the blob at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * @param content - The content of the blob to be added to the summary tree.\n\t */\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\t/**\n\t * Adds an {@link @fluidframework/driver-definitions#ISummaryHandle} that references a subtree, blob, or attachment in a previous summary.\n\t *\n\t * @param key - The key to store the handle at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * @param handleType - the type of {@link @fluidframework/driver-definitions#SummaryObject} besides a SummaryHandle, i.e. {@link @fluidframework/driver-definitions#SummaryType.Tree}, {@link @fluidframework/driver-definitions#SummaryType.Blob}, {@link @fluidframework/driver-definitions#SummaryType.Attachment}\n\t * @param handle - The path pointing to the part of the previous summary being used to duplicate the data. Use {@link @fluidframework/driver-definitions#ISummaryHandle.handle} to help generate proper handle strings. Should not contain any \"/\" characters.\n\t */\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\t/**\n\t * Adds a child and updates the stats accordingly.\n\t * @param key - The key to store the handle at in the current summary tree being generated. Should not contain any \"/\" characters.\n\t * The key should be unique within the current summary tree, and not transform when encodeURIComponent is called.\n\t * @param summarizeResult - Similar to {@link @fluidframework/runtime-definitions#ISummaryTreeWithStats}. The provided summary can be either a {@link @fluidframework/driver-definitions#ISummaryHandle} or {@link @fluidframework/driver-definitions#ISummaryTree}.\n\t */\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\t/**\n\t * Adds an {@link @fluidframework/driver-definitions#ISummaryAttachment} to the summary. This blob needs to already be uploaded to storage.\n\t * @param id - The id of the uploaded attachment to be added to the summary tree.\n\t */\n\tpublic addAttachment(id: string): void {\n\t\tthis.summaryTree[this.attachmentCounter++] = { id, type: SummaryType.Attachment };\n\t}\n\n\t/**\n\t * Gives you the in-memory summary tree with stats built by the SummaryTreeBuilder.\n\t *\n\t * @remarks\n\t * Use this once you're done building the summary tree, the stats should automatically be generated.\n\t * @returns The summary tree and stats built by the SummaryTreeBuilder.\n\t */\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 * @legacy @beta\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\" ? IsoBuffer.from(blob.contents, \"base64\") : 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\t}\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(\n\tsnapshot: ITree,\n\tfullTree: boolean = false,\n): 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\t// TODO Why are we non null asserting here?\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst content: ArrayBufferLike = snapshot.blobsContents[id]!;\n\t\t\tif (content !== undefined) {\n\t\t\t\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- External on-disk format is 'utf-8'.\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\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- external contract uses 'utf-8'.\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\t}\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 | undefined,\n\taddedGCOutboundRoute: (fromNodeId: string, toPath: string) => void,\n): boolean {\n\tconst gcDataEntry = snapshot?.entries.find((e) => e.path === gcDataBlobKey);\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\t// Cannot change \"utf-8\" to \"utf8\" as this encoding value is stored in summaries and would be a breaking change which needs to be done first before changing to utf8.\n\t\t// eslint-disable-next-line unicorn/text-encoding-identifier-case -- external contract uses 'utf-8'.\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\t// Type assertion is safe as we expect the GC data to conform to IGarbageCollectionData schema\n\tconst gcData = JSON.parse(gcDataEntry.value.contents) as IGarbageCollectionData;\n\tfor (const [nodeId, outboundRoutes] of Object.entries(gcData.gcNodes)) {\n\t\tfor (const toPath of outboundRoutes) {\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, ITelemetryContextExt {\n\tprivate readonly telemetry = new Map<string, TelemetryEventPropertyTypeExt>();\n\n\t/**\n\t * {@inheritDoc @fluidframework/runtime-definitions#ITelemetryContext.set}\n\t */\n\tpublic set(prefix: string, property: string, value: TelemetryEventPropertyTypeExt): 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\tpublic setMultiple(\n\t\tprefix: string,\n\t\tproperty: string,\n\t\tvalues: Record<string, TelemetryEventPropertyTypeExt>,\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 * Get the telemetry data being tracked\n\t * @param prefix - unique prefix to tag this data with (ex: \"fluid:map:\")\n\t * @param property - property name of the telemetry data being tracked (ex: \"DirectoryCount\")\n\t * @returns undefined if item not found\n\t */\n\tpublic get(prefix: string, property: string): TelemetryEventPropertyTypeExt {\n\t\treturn this.telemetry.get(`${prefix}${property}`);\n\t}\n\n\t/**\n\t * Returns a serialized version of all the telemetry data.\n\t * Should be used when logging in telemetry events.\n\t */\n\tpublic serialize(): string {\n\t\tconst jsonObject = {};\n\t\tfor (const [key, value] of this.telemetry.entries()) {\n\t\t\tjsonObject[key] = value;\n\t\t}\n\t\treturn JSON.stringify(jsonObject);\n\t}\n\n\tpublic getCurrentSummarizeStep(): TelemetryEventPropertyTypeExt {\n\t\treturn this.get(currentSummarizeStepPrefix, currentSummarizeStepPropertyName);\n\t}\n\n\tpublic setCurrentSummarizeStep(value: TelemetryEventPropertyTypeExt): void {\n\t\tthis.set(currentSummarizeStepPrefix, currentSummarizeStepPropertyName, value);\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): 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): 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: Record<string, Set<string>> = {};\n\tpublic get gcNodes(): Record<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[]): void {\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: Record<string, string[]>): void {\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: Record<string, string[]>): void {\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): void {\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"]}
|
package/dist/unpackUsedRoutes.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.unpackChildNodesUsedRoutes =
|
|
7
|
+
exports.unpackChildNodesUsedRoutes = unpackChildNodesUsedRoutes;
|
|
8
8
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
9
|
/**
|
|
10
10
|
* Helper function that unpacks the used routes of children from a given node's used routes.
|
|
@@ -31,5 +31,4 @@ function unpackChildNodesUsedRoutes(usedRoutes) {
|
|
|
31
31
|
}
|
|
32
32
|
return childUsedRoutesMap;
|
|
33
33
|
}
|
|
34
|
-
exports.unpackChildNodesUsedRoutes = unpackChildNodesUsedRoutes;
|
|
35
34
|
//# sourceMappingURL=unpackUsedRoutes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unpackUsedRoutes.js","sourceRoot":"","sources":["../src/unpackUsedRoutes.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"unpackUsedRoutes.js","sourceRoot":"","sources":["../src/unpackUsedRoutes.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAUH,gEAuBC;AA/BD,kEAA6D;AAE7D;;;;;GAKG;AACH,SAAgB,0BAA0B,CACzC,UAA6B;IAE7B,oFAAoF;IACpF,MAAM,kBAAkB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC;IACvF,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAoB,CAAC;IACvD,KAAK,MAAM,KAAK,IAAI,kBAAkB,EAAE,CAAC;QACxC,IAAA,iBAAM,EAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzF,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,IAAA,iBAAM,EACL,OAAO,KAAK,SAAS,EACrB,KAAK,CAAC,wDAAwD,CAC9D,CAAC;QACF,MAAM,cAAc,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAEvD,MAAM,eAAe,GAAG,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;YACnC,kBAAkB,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;QACnD,CAAC;aAAM,CAAC;YACP,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACtC,CAAC;IACF,CAAC;IACD,OAAO,kBAAkB,CAAC;AAC3B,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\n/**\n * Helper function that unpacks the used routes of children from a given node's used routes.\n * @param usedRoutes - The used routes of a node.\n * @returns A map of used routes of each children of the the given node.\n * @internal\n */\nexport function unpackChildNodesUsedRoutes(\n\tusedRoutes: readonly string[],\n): Map<string, string[]> {\n\t// Remove the node's self used route, if any, and generate the children used routes.\n\tconst filteredUsedRoutes = usedRoutes.filter((route) => route !== \"\" && route !== \"/\");\n\tconst childUsedRoutesMap = new Map<string, string[]>();\n\tfor (const route of filteredUsedRoutes) {\n\t\tassert(route.startsWith(\"/\"), 0x5e0 /* Used route should always be an absolute route */);\n\t\tconst childId = route.split(\"/\")[1];\n\t\tassert(\n\t\t\tchildId !== undefined,\n\t\t\t0x9ab /* childId is undefined in unpackChildNodesUsedRoutes */,\n\t\t);\n\t\tconst childUsedRoute = route.slice(childId.length + 1);\n\n\t\tconst childUsedRoutes = childUsedRoutesMap.get(childId);\n\t\tif (childUsedRoutes === undefined) {\n\t\t\tchildUsedRoutesMap.set(childId, [childUsedRoute]);\n\t\t} else {\n\t\t\tchildUsedRoutes.push(childUsedRoute);\n\t\t}\n\t}\n\treturn childUsedRoutesMap;\n}\n"]}
|
package/dist/utils.js
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
7
|
+
exports.charSetForEncodingIds = exports.RuntimeHeaders = void 0;
|
|
8
|
+
exports.seqFromTree = seqFromTree;
|
|
9
|
+
exports.encodeCompactIdToString = encodeCompactIdToString;
|
|
8
10
|
const internal_1 = require("@fluidframework/core-utils/internal");
|
|
9
11
|
/**
|
|
10
12
|
* Accepted header keys for requests coming to the runtime.
|
|
@@ -39,7 +41,6 @@ async function seqFromTree(tree, readAndParseBlob) {
|
|
|
39
41
|
const attrib = await readAndParseBlob(attributesHash);
|
|
40
42
|
return attrib.sequenceNumber;
|
|
41
43
|
}
|
|
42
|
-
exports.seqFromTree = seqFromTree;
|
|
43
44
|
/**
|
|
44
45
|
* The following characters emulates the UTF-16 code sequence from 65 - 123, except for the `[` and `{`
|
|
45
46
|
* positioned at 91 and 123 respectively - which are changed to '(' and ')'. Used in the `encodeCompactIdToString` utility below.
|
|
@@ -91,5 +92,4 @@ function encodeCompactIdToString(idArg, prefix = "") {
|
|
|
91
92
|
} while (num !== -1);
|
|
92
93
|
return prefix + id;
|
|
93
94
|
}
|
|
94
|
-
exports.encodeCompactIdToString = encodeCompactIdToString;
|
|
95
95
|
//# sourceMappingURL=utils.js.map
|
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAyCH,kCASC;AA0BD,0DA6BC;AAvGD,kEAA6D;AAM7D;;;GAGG;AACH,IAAY,cAaX;AAbD,WAAY,cAAc;IACzB;;OAEG;IACH,+BAAa,CAAA;IACb;;OAEG;IACH,yCAAuB,CAAA;IACvB;;OAEG;IACH,mDAAiC,CAAA;AAClC,CAAC,EAbW,cAAc,8BAAd,cAAc,QAazB;AASD;;;;;;GAMG;AACI,KAAK,UAAU,WAAW,CAChC,IAAmB,EACnB,gBAAkC;IAElC,2CAA2C;IAC3C,oEAAoE;IACpE,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAE,CAAC,KAAK,CAAC,UAAW,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAsB,cAAc,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC,cAAc,CAAC;AAC9B,CAAC;AAED;;;;;;;GAOG;AACU,QAAA,qBAAqB,GACjC,kEAAkE,CAAC;AAEpE;;;;;;;;;;;;GAYG;AACH,SAAgB,uBAAuB,CAAC,KAAsB,EAAE,MAAM,GAAG,EAAE;IAC1E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACd,CAAC;IAED,0DAA0D;IAC1D,yEAAyE;IACzE,wFAAwF;IACxF,iEAAiE;IACjE,8FAA8F;IAC9F,gDAAgD;IAChD,8EAA8E;IAC9E,wDAAwD;IACxD,IAAA,iBAAM,EAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACzE,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,GAAG,CAAC;QACH,gDAAgD;QAChD,WAAW;QACX,WAAW;QACX,aAAa;QACb,cAAc;QACd,iBAAiB;QACjB,kBAAkB;QAClB,MAAM,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC;QACxB,EAAE,GAAG,6BAAqB,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACxC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,EAAE;IACrB,OAAO,MAAM,GAAG,EAAE,CAAC;AACpB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\nimport type {\n\tIDocumentAttributes,\n\tISnapshotTree,\n} from \"@fluidframework/driver-definitions/internal\";\n\n/**\n * Accepted header keys for requests coming to the runtime.\n * @internal\n */\nexport enum RuntimeHeaders {\n\t/**\n\t * True to wait for a data store to be created and loaded before returning it.\n\t */\n\twait = \"wait\",\n\t/**\n\t * True if the request is coming from an IFluidHandle.\n\t */\n\tviaHandle = \"viaHandle\",\n\t/**\n\t * True if the request is coming from a handle with a pending payload.\n\t */\n\tpayloadPending = \"payloadPending\",\n}\n\n/**\n * Reads a blob from storage and parses it from JSON.\n *\n * @internal\n */\nexport type ReadAndParseBlob = <T>(id: string) => Promise<T>;\n\n/**\n * Fetches the sequence number of the snapshot tree by examining the protocol.\n * @param tree - snapshot tree to examine\n * @param readAndParseBlob - function to read blob contents from storage\n * and parse the result from JSON.\n * @internal\n */\nexport async function seqFromTree(\n\ttree: ISnapshotTree,\n\treadAndParseBlob: ReadAndParseBlob,\n): Promise<number> {\n\t// TODO why are we non null asserting here?\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tconst attributesHash = tree.trees[\".protocol\"]!.blobs.attributes!;\n\tconst attrib = await readAndParseBlob<IDocumentAttributes>(attributesHash);\n\treturn attrib.sequenceNumber;\n}\n\n/**\n * The following characters emulates the UTF-16 code sequence from 65 - 123, except for the `[` and `{`\n * positioned at 91 and 123 respectively - which are changed to '(' and ')'. Used in the `encodeCompactIdToString` utility below.\n * NOTE: The character set must never be changed - since it could result in collisions with existing ids.\n * If changing, make sure to choose new characters that have never been\n * used before, and the characters must not change their encoding with 'encodeURIComponent'.\n * @internal\n */\nexport const charSetForEncodingIds =\n\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZ(abcdefghijklmnopqrstuvwxyz)0123456789\";\n\n/**\n * Encode compact ID (returned by IContainerRuntime.generateDocumentUniqueId()) to a compact string representation.\n * While this is the main usage pattern, it works with any non-negative integer or a string.\n * Strings are returned as is, and assumed to be UUIDs, i.e. unique enough to never overlap with\n * numbers encoded as strings by this function. Any other strings are likely to run into collisions and should not be used!\n * This function is useful in places where we serialize resulting ID as string and use them as strings, thus we are not\n * gaining any efficiency from having a number type.\n * 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 original form.\n * @param idArg - input - either a non-negative integer or a string. Strings are returned as is, while numbers are encoded in compat form\n * @param prefix - optional string prefix\n * @returns A string - representation of an input\n * @internal\n */\nexport function encodeCompactIdToString(idArg: number | string, prefix = \"\"): string {\n\tif (typeof idArg === \"string\") {\n\t\treturn idArg;\n\t}\n\n\t// WARNING: result of this function are stored in storage!\n\t// If you ever need to change this function, you will need to ensure that\n\t// for any inputs N1 & N2, old(N1) !== new(N2), where old() - is the old implementation,\n\t// and new() - is new implementation of encodeCompactIdToString()\n\t// This likely means - this function can't be changed, unless it uses some prefix that ensures\n\t// new values have zero overlap with old values.\n\t// Also resulting string can't contain \"/\", as that's disallowed by some users\n\t// (data store and DDS IDs can't have \"/\" in their IDs).\n\tassert(Number.isInteger(idArg) && idArg >= 0, 0x900 /* invalid input */);\n\tlet id = \"\";\n\tlet num = idArg;\n\tdo {\n\t\t// Here are some examples of the input & output:\n\t\t// 0 -> 'A'\n\t\t// 1 -> 'B'\n\t\t// 64 -> \"AA\"\n\t\t// 100 -> 'Aj'\n\t\t// 10000 -> 'BaQ'\n\t\t// 100000 -> 'XZf'\n\t\tconst encode = num % 64;\n\t\tid = charSetForEncodingIds[encode] + id;\n\t\tnum = Math.floor(num / 64) - 1;\n\t} while (num !== -1);\n\treturn prefix + id;\n}\n"]}
|
|
@@ -4,51 +4,36 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { OldestSupportedClientVersion } from "@fluidframework/runtime-definitions/internal";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* recent public major release of the Fluid Framework Client.
|
|
9
|
-
* Therefore, if the customer does not provide a minVersionForCollab, we will
|
|
10
|
-
* default to use N-1.
|
|
11
|
-
*
|
|
12
|
-
* However, this is not consistent with today's behavior. Some options (i.e.
|
|
13
|
-
* batching, compression) are enabled by default despite not being compatible
|
|
14
|
-
* with 1.x clients. Since the policy was introduced during 2.x's lifespan,
|
|
15
|
-
* N/N-1 compatibility by **default** will be in effect starting with 3.0.
|
|
16
|
-
* Importantly though, N/N-2 compatibility is still guaranteed with the proper
|
|
17
|
-
* configurations set.
|
|
18
|
-
*
|
|
19
|
-
* Further to distinguish unspecified `minVersionForCollab` from a specified
|
|
20
|
-
* version and allow `enableExplicitSchemaControl` to default to `true` for
|
|
21
|
-
* any 2.0.0+ version, we will use a special value of `2.0.0-defaults`, which
|
|
22
|
-
* is semantically less than 2.0.0.
|
|
7
|
+
* Oldest deployed Fluid Framework client version supported for cross-client compatibility.
|
|
23
8
|
*
|
|
24
9
|
* @internal
|
|
25
10
|
*/
|
|
26
|
-
export declare const
|
|
11
|
+
export declare const lowestMinVersionForCollab: "2.0.0";
|
|
27
12
|
/**
|
|
28
|
-
*
|
|
29
|
-
* Today we use "1.0.0", because our policy supports N/N-1 & N/N-2, which includes
|
|
30
|
-
* all minor versions of N. Though LTS starts at 1.4.0, we should stay consistent
|
|
31
|
-
* with our policy and allow all 1.x versions to be compatible with 2.x.
|
|
13
|
+
* Default oldest supported client for APIs that still permit the setting to be omitted.
|
|
32
14
|
*
|
|
33
|
-
* @
|
|
34
|
-
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* This aliases {@link lowestMinVersionForCollab} in Client 3.0. Remove this fallback when
|
|
17
|
+
* customer-facing APIs require `oldestSupportedClient` in Client 3.10.
|
|
18
|
+
* See {@link https://github.com/microsoft/FluidFramework/issues/27180}.
|
|
35
19
|
*
|
|
36
20
|
* @internal
|
|
37
21
|
*/
|
|
38
|
-
export declare const
|
|
22
|
+
export declare const defaultMinVersionForCollab: "2.0.0";
|
|
39
23
|
/**
|
|
40
|
-
* String in a valid semver format specifying bottom of a minor version
|
|
41
|
-
*
|
|
42
|
-
* @remarks
|
|
43
|
-
*
|
|
24
|
+
* String in a valid semver format specifying the bottom of a minor version.
|
|
25
|
+
*
|
|
26
|
+
* @remarks
|
|
27
|
+
* Configuration maps use major/minor checkpoints. Exact patch and prerelease versions are values
|
|
28
|
+
* supplied to the selection logic, not configuration-map keys.
|
|
44
29
|
*
|
|
45
30
|
* @internal
|
|
46
31
|
*/
|
|
47
|
-
export type MinimumMinorSemanticVersion = `${bigint}.${bigint}.0
|
|
32
|
+
export type MinimumMinorSemanticVersion = `${bigint}.${bigint}.0`;
|
|
48
33
|
/**
|
|
49
34
|
* String in a valid semver format of a specific version at least specifying minor.
|
|
50
|
-
* Unlike {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}, this type
|
|
51
|
-
*
|
|
35
|
+
* Unlike {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}, this type does
|
|
36
|
+
* not encode the active compatibility floor or major-specific patch restrictions.
|
|
52
37
|
*
|
|
53
38
|
* @internal
|
|
54
39
|
*/
|
|
@@ -134,6 +119,7 @@ export declare function checkValidMinVersionForCollabVerbose(minVersionForCollab
|
|
|
134
119
|
isValidSemver: boolean;
|
|
135
120
|
isGteLowestMinVersion: boolean;
|
|
136
121
|
isLtePkgVersion: boolean;
|
|
122
|
+
isValidOldestSupportedClientVersion: boolean;
|
|
137
123
|
};
|
|
138
124
|
/**
|
|
139
125
|
* Checks if the minVersionForCollab is valid.
|
|
@@ -143,32 +129,21 @@ export declare function checkValidMinVersionForCollabVerbose(minVersionForCollab
|
|
|
143
129
|
*/
|
|
144
130
|
export declare function isValidMinVersionForCollab(minVersionForCollab: SemanticVersion): minVersionForCollab is OldestSupportedClientVersion;
|
|
145
131
|
/**
|
|
146
|
-
* `pkgVersion` version without pre-release.
|
|
132
|
+
* `pkgVersion` version without pre-release and with zeroed patch.
|
|
147
133
|
* @remarks
|
|
148
|
-
* This is the version
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* it makes sense for them to claim to support the same features as the following release so they can be used to test how the release would actually behave.
|
|
152
|
-
*
|
|
153
|
-
* To accomplish this, the version the next release will have is provided here as `cleanedPackageVersion` while `pkgVersion` may be a prerelease in some cases,
|
|
154
|
-
* like when running tests on CI, or in an actual prerelease published package.
|
|
155
|
-
* This is then used in {@link validateMinimumVersionForCollab} to allow the version shown on main to be usable as a `minVersionForCollab`, even in CI and prerelease packages.
|
|
134
|
+
* This is the version the current codebase will have when officially released.
|
|
135
|
+
* It allows CI and prerelease builds to test the release's features using that version as their
|
|
136
|
+
* `OldestSupportedClientVersion`.
|
|
156
137
|
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* Having that version be valid on main, pass tests locally, then fail on CI and when using published prerelease packages would be confusing, and probably undesired.
|
|
160
|
-
* 2. Setting the minVersionForCollab to the current version for scenarios that do no involve collab with other package versions seems like it should be valid.
|
|
161
|
-
* This is useful for testing new features, and also non collaborative scenarios where the latest features are desired.
|
|
162
|
-
*
|
|
163
|
-
* To accommodate some uses of the second case, it might be useful to package export this in the future.
|
|
138
|
+
* Code that needs to derive this value from a package version should use
|
|
139
|
+
* {@link @fluidframework/driver-definitions#featureVersion}.
|
|
164
140
|
*
|
|
165
141
|
* @privateRemarks
|
|
166
|
-
*
|
|
167
|
-
* Thus this is just `as` cast here, and a test confirms it is valid according to validateMinimumVersionForCollab.
|
|
142
|
+
* This value is validated against {@link validateMinimumVersionForCollab} by a test.
|
|
168
143
|
*
|
|
169
144
|
* @internal
|
|
170
145
|
*/
|
|
171
|
-
export declare const cleanedPackageVersion:
|
|
146
|
+
export declare const cleanedPackageVersion: "3.0.0";
|
|
172
147
|
/**
|
|
173
148
|
* Narrows the type of the provided {@link SemanticVersion} to a {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}, throwing a UsageError if it is not valid.
|
|
174
149
|
* @remarks
|
|
@@ -184,14 +159,12 @@ export declare function validateMinimumVersionForCollab(semanticVersion: string)
|
|
|
184
159
|
/**
|
|
185
160
|
* Validates the given `overrides`.
|
|
186
161
|
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* Otherwise this checks that for keys which are in both the `validationMap` and the `overrides`,
|
|
162
|
+
* Checks that for keys which are in both the `validationMap` and the `overrides`,
|
|
190
163
|
* that the `validationMap` function for that key either returns undefined or a version less than or equal to `minVersionForCollab`.
|
|
191
164
|
* @privateRemarks
|
|
192
165
|
* This design seems odd, and might want to be revisited.
|
|
193
166
|
* Currently it only permits opting out of features, not into them (unless validationMap returns undefined),
|
|
194
|
-
* and the handling of
|
|
167
|
+
* and the handling of undefined versions seems questionable.
|
|
195
168
|
* Also ignoring of extra keys in overrides might be bad since it seems like overrides is supposed to be validated.
|
|
196
169
|
* @internal
|
|
197
170
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compatibilityBase.d.ts","sourceRoot":"","sources":["../src/compatibilityBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,8CAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"compatibilityBase.d.ts","sourceRoot":"","sources":["../src/compatibilityBase.ts"],"names":[],"mappings":"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"}
|
package/lib/compatibilityBase.js
CHANGED
|
@@ -4,41 +4,26 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { assert, fail } from "@fluidframework/core-utils/internal";
|
|
6
6
|
import { UsageError } from "@fluidframework/telemetry-utils/internal";
|
|
7
|
-
import {
|
|
7
|
+
import { featureVersion } from "@fluidframework/driver-definitions/internal";
|
|
8
|
+
import { compare, gt, gte, lte, parse } from "semver-ts";
|
|
8
9
|
import { pkgVersion } from "./packageVersion.js";
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
-
* recent public major release of the Fluid Framework Client.
|
|
12
|
-
* Therefore, if the customer does not provide a minVersionForCollab, we will
|
|
13
|
-
* default to use N-1.
|
|
14
|
-
*
|
|
15
|
-
* However, this is not consistent with today's behavior. Some options (i.e.
|
|
16
|
-
* batching, compression) are enabled by default despite not being compatible
|
|
17
|
-
* with 1.x clients. Since the policy was introduced during 2.x's lifespan,
|
|
18
|
-
* N/N-1 compatibility by **default** will be in effect starting with 3.0.
|
|
19
|
-
* Importantly though, N/N-2 compatibility is still guaranteed with the proper
|
|
20
|
-
* configurations set.
|
|
21
|
-
*
|
|
22
|
-
* Further to distinguish unspecified `minVersionForCollab` from a specified
|
|
23
|
-
* version and allow `enableExplicitSchemaControl` to default to `true` for
|
|
24
|
-
* any 2.0.0+ version, we will use a special value of `2.0.0-defaults`, which
|
|
25
|
-
* is semantically less than 2.0.0.
|
|
11
|
+
* Oldest deployed Fluid Framework client version supported for cross-client compatibility.
|
|
26
12
|
*
|
|
27
13
|
* @internal
|
|
28
14
|
*/
|
|
29
|
-
export const
|
|
15
|
+
export const lowestMinVersionForCollab = "2.0.0";
|
|
30
16
|
/**
|
|
31
|
-
*
|
|
32
|
-
* Today we use "1.0.0", because our policy supports N/N-1 & N/N-2, which includes
|
|
33
|
-
* all minor versions of N. Though LTS starts at 1.4.0, we should stay consistent
|
|
34
|
-
* with our policy and allow all 1.x versions to be compatible with 2.x.
|
|
17
|
+
* Default oldest supported client for APIs that still permit the setting to be omitted.
|
|
35
18
|
*
|
|
36
|
-
* @
|
|
37
|
-
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* This aliases {@link lowestMinVersionForCollab} in Client 3.0. Remove this fallback when
|
|
21
|
+
* customer-facing APIs require `oldestSupportedClient` in Client 3.10.
|
|
22
|
+
* See {@link https://github.com/microsoft/FluidFramework/issues/27180}.
|
|
38
23
|
*
|
|
39
24
|
* @internal
|
|
40
25
|
*/
|
|
41
|
-
export const
|
|
26
|
+
export const defaultMinVersionForCollab = lowestMinVersionForCollab;
|
|
42
27
|
/**
|
|
43
28
|
* Returns a default configuration given minVersionForCollab and configuration version map.
|
|
44
29
|
*
|
|
@@ -116,12 +101,20 @@ export function selectVersionRoundedDown(minVersionForCollab, entries, compareVe
|
|
|
116
101
|
* @internal
|
|
117
102
|
*/
|
|
118
103
|
export function checkValidMinVersionForCollabVerbose(minVersionForCollab) {
|
|
119
|
-
const
|
|
104
|
+
const parsed = parse(minVersionForCollab);
|
|
105
|
+
const isValidSemver = parsed !== null && parsed.build.length === 0;
|
|
106
|
+
const isGteLowestMinVersion = isValidSemver && gte(minVersionForCollab, lowestMinVersionForCollab);
|
|
107
|
+
const isLtePkgVersion = isValidSemver && lte(minVersionForCollab, cleanedPackageVersion);
|
|
108
|
+
const isValidOldestSupportedClientVersion = isGteLowestMinVersion &&
|
|
109
|
+
isLtePkgVersion &&
|
|
110
|
+
parsed !== null &&
|
|
111
|
+
parsed.prerelease.length === 0 &&
|
|
112
|
+
(parsed.major < 3 || parsed.patch === 0);
|
|
120
113
|
return {
|
|
121
114
|
isValidSemver,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
115
|
+
isGteLowestMinVersion,
|
|
116
|
+
isLtePkgVersion,
|
|
117
|
+
isValidOldestSupportedClientVersion,
|
|
125
118
|
};
|
|
126
119
|
}
|
|
127
120
|
/**
|
|
@@ -131,37 +124,25 @@ export function checkValidMinVersionForCollabVerbose(minVersionForCollab) {
|
|
|
131
124
|
* @internal
|
|
132
125
|
*/
|
|
133
126
|
export function isValidMinVersionForCollab(minVersionForCollab) {
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
return checkValidMinVersionForCollabVerbose(minVersionForCollab)
|
|
128
|
+
.isValidOldestSupportedClientVersion;
|
|
136
129
|
}
|
|
137
|
-
const parsedPackageVersion = parse(pkgVersion) ?? fail(0xcb9 /* Invalid package version */);
|
|
138
130
|
/**
|
|
139
|
-
* `pkgVersion` version without pre-release.
|
|
131
|
+
* `pkgVersion` version without pre-release and with zeroed patch.
|
|
140
132
|
* @remarks
|
|
141
|
-
* This is the version
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
* it makes sense for them to claim to support the same features as the following release so they can be used to test how the release would actually behave.
|
|
133
|
+
* This is the version the current codebase will have when officially released.
|
|
134
|
+
* It allows CI and prerelease builds to test the release's features using that version as their
|
|
135
|
+
* `OldestSupportedClientVersion`.
|
|
145
136
|
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* This is then used in {@link validateMinimumVersionForCollab} to allow the version shown on main to be usable as a `minVersionForCollab`, even in CI and prerelease packages.
|
|
149
|
-
*
|
|
150
|
-
* This is of particular note in two cases:
|
|
151
|
-
* 1. When landing a new feature, and setting the minVersionForCollab which enables it to be the version that the next release will have.
|
|
152
|
-
* Having that version be valid on main, pass tests locally, then fail on CI and when using published prerelease packages would be confusing, and probably undesired.
|
|
153
|
-
* 2. Setting the minVersionForCollab to the current version for scenarios that do no involve collab with other package versions seems like it should be valid.
|
|
154
|
-
* This is useful for testing new features, and also non collaborative scenarios where the latest features are desired.
|
|
155
|
-
*
|
|
156
|
-
* To accommodate some uses of the second case, it might be useful to package export this in the future.
|
|
137
|
+
* Code that needs to derive this value from a package version should use
|
|
138
|
+
* {@link @fluidframework/driver-definitions#featureVersion}.
|
|
157
139
|
*
|
|
158
140
|
* @privateRemarks
|
|
159
|
-
*
|
|
160
|
-
* Thus this is just `as` cast here, and a test confirms it is valid according to validateMinimumVersionForCollab.
|
|
141
|
+
* This value is validated against {@link validateMinimumVersionForCollab} by a test.
|
|
161
142
|
*
|
|
162
143
|
* @internal
|
|
163
144
|
*/
|
|
164
|
-
export const cleanedPackageVersion =
|
|
145
|
+
export const cleanedPackageVersion = featureVersion(pkgVersion);
|
|
165
146
|
/**
|
|
166
147
|
* Narrows the type of the provided {@link SemanticVersion} to a {@link @fluidframework/runtime-definitions#OldestSupportedClientVersion}, throwing a UsageError if it is not valid.
|
|
167
148
|
* @remarks
|
|
@@ -175,35 +156,29 @@ export const cleanedPackageVersion = `${parsedPackageVersion.major}.${parsedPack
|
|
|
175
156
|
*/
|
|
176
157
|
export function validateMinimumVersionForCollab(semanticVersion) {
|
|
177
158
|
const minVersionForCollab = semanticVersion;
|
|
178
|
-
const { isValidSemver, isGteLowestMinVersion, isLtePkgVersion } = checkValidMinVersionForCollabVerbose(minVersionForCollab);
|
|
179
|
-
if (!
|
|
159
|
+
const { isValidSemver, isGteLowestMinVersion, isLtePkgVersion, isValidOldestSupportedClientVersion, } = checkValidMinVersionForCollabVerbose(minVersionForCollab);
|
|
160
|
+
if (!isValidOldestSupportedClientVersion) {
|
|
180
161
|
throw new UsageError(`Version ${minVersionForCollab} is not a valid OldestSupportedClientVersion. ` +
|
|
181
162
|
`It must be in a valid semver format, at least ${lowestMinVersionForCollab}, ` +
|
|
182
|
-
`
|
|
183
|
-
`
|
|
163
|
+
`less than or equal to the current package version ${cleanedPackageVersion}, ` +
|
|
164
|
+
`have no prerelease component, and use patch version 0 for major version 3 and later. ` +
|
|
165
|
+
`Use "featureVersion" to normalize a package version to the correct format. ` +
|
|
166
|
+
`Details: { isValidSemver: ${isValidSemver}, isGteLowestMinVersion: ${isGteLowestMinVersion}, isLtePkgVersion: ${isLtePkgVersion}, isValidOldestSupportedClientVersion: ${isValidOldestSupportedClientVersion} }`);
|
|
184
167
|
}
|
|
185
168
|
}
|
|
186
169
|
/**
|
|
187
170
|
* Validates the given `overrides`.
|
|
188
171
|
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
* Otherwise this checks that for keys which are in both the `validationMap` and the `overrides`,
|
|
172
|
+
* Checks that for keys which are in both the `validationMap` and the `overrides`,
|
|
192
173
|
* that the `validationMap` function for that key either returns undefined or a version less than or equal to `minVersionForCollab`.
|
|
193
174
|
* @privateRemarks
|
|
194
175
|
* This design seems odd, and might want to be revisited.
|
|
195
176
|
* Currently it only permits opting out of features, not into them (unless validationMap returns undefined),
|
|
196
|
-
* and the handling of
|
|
177
|
+
* and the handling of undefined versions seems questionable.
|
|
197
178
|
* Also ignoring of extra keys in overrides might be bad since it seems like overrides is supposed to be validated.
|
|
198
179
|
* @internal
|
|
199
180
|
*/
|
|
200
181
|
export function validateConfigMapOverrides(minVersionForCollab, overrides, validationMap) {
|
|
201
|
-
if (minVersionForCollab === defaultMinVersionForCollab) {
|
|
202
|
-
// If the minVersionForCollab is set to the default value, then we will not validate the runtime options
|
|
203
|
-
// This is to avoid disruption to users who have not yet set the minVersionForCollab value explicitly.
|
|
204
|
-
// TODO: This also skips validation for users which explicitly request defaultMinVersionForCollab which seems like a bug.
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
182
|
// Iterate through each runtime option passed in by the user
|
|
208
183
|
// Type assertion is safe as entries come from runtimeOptions object
|
|
209
184
|
for (const [passedRuntimeOption, passedRuntimeOptionValue] of Object.entries(overrides)) {
|