@fluidframework/odsp-driver 1.2.7 → 1.3.0-97515
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/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +1 -4
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +3 -6
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +24 -22
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +23 -31
- package/dist/getFileLink.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +2 -1
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +5 -4
- package/dist/odspDeltaStorageService.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/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +1 -4
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +3 -6
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +24 -22
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +25 -33
- package/lib/getFileLink.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +2 -1
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +5 -4
- package/lib/odspDeltaStorageService.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/package.json +11 -11
- package/src/compactSnapshotParser.ts +1 -3
- package/src/compactSnapshotWriter.ts +3 -6
- package/src/fetchSnapshot.ts +33 -24
- package/src/getFileLink.ts +29 -32
- package/src/odspDeltaStorageService.ts +4 -2
- package/src/packageVersion.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"compactSnapshotParser.d.ts","sourceRoot":"","sources":["../src/compactSnapshotParser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAa/C,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AAgGxC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2BlF"}
|
|
@@ -60,13 +60,10 @@ function readTreeSection(node) {
|
|
|
60
60
|
(0, zipItDataRepresentationUtils_1.assertBlobCoreInstance)(records.value, "Blob value should be BlobCore");
|
|
61
61
|
snapshotTree.blobs[path] = records.value.toString();
|
|
62
62
|
}
|
|
63
|
-
else
|
|
63
|
+
else {
|
|
64
64
|
(0, zipItDataRepresentationUtils_1.assertNodeCoreInstance)(records.children, "Trees should be of type NodeCore");
|
|
65
65
|
snapshotTree.trees[path] = readTreeSection(records.children);
|
|
66
66
|
}
|
|
67
|
-
else {
|
|
68
|
-
snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };
|
|
69
|
-
}
|
|
70
67
|
if (records.unreferenced !== undefined) {
|
|
71
68
|
(0, zipItDataRepresentationUtils_1.assertBoolInstance)(records.unreferenced, "Unreferenced flag should be bool");
|
|
72
69
|
const unreferenced = records.unreferenced.valueOf();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.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 { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else if (records.children !== undefined) {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n } else {\n snapshotTree.trees[path] = { blobs: {}, commits: {}, trees: {} };\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"compactSnapshotParser.js","sourceRoot":"","sources":["../src/compactSnapshotParser.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 { assert } from \"@fluidframework/common-utils\";\nimport { ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { ISnapshotTreeEx } from \"./contracts\";\nimport {\n assertBlobCoreInstance,\n assertBoolInstance,\n assertNodeCoreInstance,\n assertNumberInstance,\n getAndValidateNodeProps,\n NodeCore,\n NodeTypes,\n TreeBuilder,\n} from \"./zipItDataRepresentationUtils\";\n\nexport const snapshotMinReadVersion = \"1.0\";\nexport const currentReadVersion = \"1.0\";\n\ninterface ISnapshotSection {\n snapshotTree: ISnapshotTree;\n sequenceNumber: number;\n}\n\n/**\n * Recreates blobs section of the tree.\n * @param node - tree node to read blob section from\n */\nfunction readBlobSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"TreeBlobs should be of type NodeCore\");\n const blobs: Map<string, ArrayBuffer> = new Map();\n for (let count = 0; count < node.length; ++count) {\n const blob = node.getNode(count);\n const records = getAndValidateNodeProps(blob, [\"id\", \"data\"]);\n assertBlobCoreInstance(records.data, \"data should be of BlobCore type\");\n assertBlobCoreInstance(records.id, \"blob id should be of BlobCore type\");\n blobs.set(records.id.toString(), records.data.arrayBuffer);\n }\n return blobs;\n}\n\n/**\n * Recreates ops section of the tree.\n * @param node - tree node to read ops section from\n */\nfunction readOpsSection(node: NodeTypes) {\n assertNodeCoreInstance(node, \"Deltas should be of type NodeCore\");\n const ops: ISequencedDocumentMessage[] = [];\n const records = getAndValidateNodeProps(node, [\"firstSequenceNumber\", \"deltas\"]);\n assertNumberInstance(records.firstSequenceNumber, \"Seq number should be a number\");\n assertNodeCoreInstance(records.deltas, \"Deltas should be a Node\");\n for (let i = 0; i < records.deltas.length; ++i) {\n ops.push(JSON.parse(records.deltas.getString(i)));\n }\n assert(records.firstSequenceNumber.valueOf() === ops[0].sequenceNumber,\n 0x280 /* \"Validate first op seq number\" */);\n return ops;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readTreeSection(node: NodeCore) {\n const snapshotTree: ISnapshotTreeEx = {\n blobs: {},\n commits: {},\n trees: {},\n };\n for (let count = 0; count < node.length; count++) {\n const treeNode = node.getNode(count);\n const records = getAndValidateNodeProps(treeNode,\n [\"name\", \"value\", \"children\", \"unreferenced\"], false);\n assertBlobCoreInstance(records.name, \"Path should be of BlobCore\");\n const path = records.name.toString();\n if (records.value !== undefined) {\n assertBlobCoreInstance(records.value, \"Blob value should be BlobCore\");\n snapshotTree.blobs[path] = records.value.toString();\n } else {\n assertNodeCoreInstance(records.children, \"Trees should be of type NodeCore\");\n snapshotTree.trees[path] = readTreeSection(records.children);\n }\n if (records.unreferenced !== undefined) {\n assertBoolInstance(records.unreferenced, \"Unreferenced flag should be bool\");\n const unreferenced = records.unreferenced.valueOf();\n assert(unreferenced, 0x281 /* \"Unreferenced if present should be true\" */);\n snapshotTree.unreferenced = unreferenced;\n }\n }\n return snapshotTree;\n}\n\n/**\n * Recreates snapshot tree out of tree representation.\n * @param node - tree node to de-serialize from\n */\nfunction readSnapshotSection(node: NodeTypes): ISnapshotSection {\n assertNodeCoreInstance(node, \"Snapshot should be of type NodeCore\");\n const records = getAndValidateNodeProps(node,\n [\"id\", \"sequenceNumber\", \"treeNodes\"]);\n\n assertNodeCoreInstance(records.treeNodes, \"TreeNodes should be of type NodeCore\");\n assertNumberInstance(records.sequenceNumber, \"sequenceNumber should be of type number\");\n assertBlobCoreInstance(records.id, \"snapshotId should be BlobCore\");\n const snapshotTree: ISnapshotTree = readTreeSection(records.treeNodes);\n snapshotTree.id = records.id.toString();\n const sequenceNumber = records.sequenceNumber.valueOf();\n return {\n sequenceNumber,\n snapshotTree,\n };\n}\n\n/**\n * Converts snapshot from binary compact representation to tree/blobs/ops.\n * @param buffer - Compact snapshot to be parsed into tree/blobs/ops.\n * @returns - tree, blobs and ops from the snapshot.\n */\nexport function parseCompactSnapshotResponse(buffer: ReadBuffer): ISnapshotContents {\n const builder = TreeBuilder.load(buffer);\n assert(builder.length === 1, 0x219 /* \"1 root should be there\" */);\n const root = builder.getNode(0);\n\n const records = getAndValidateNodeProps(root,\n [\"mrv\", \"cv\", \"lsn\", \"snapshot\", \"blobs\", \"deltas\"], false);\n\n assertBlobCoreInstance(records.mrv, \"minReadVersion should be of BlobCore type\");\n assertBlobCoreInstance(records.cv, \"createVersion should be of BlobCore type\");\n if (records.lsn !== undefined) {\n assertNumberInstance(records.lsn, \"lsn should be a number\");\n }\n\n assert(parseFloat(snapshotMinReadVersion) >= parseFloat(records.mrv.toString()),\n 0x20f /* \"Driver min read version should >= to server minReadVersion\" */);\n assert(parseFloat(records.cv.toString()) >= parseFloat(snapshotMinReadVersion),\n 0x210 /* \"Snapshot should be created with minReadVersion or above\" */);\n assert(currentReadVersion === records.cv.toString(),\n 0x2c2 /* \"Create Version should be equal to currentReadVersion\" */);\n\n return {\n ...readSnapshotSection(records.snapshot),\n blobs: readBlobSection(records.blobs),\n ops: records.deltas !== undefined ? readOpsSection(records.deltas) : [],\n latestSequenceNumber: records.lsn,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"compactSnapshotWriter.d.ts","sourceRoot":"","sources":["../src/compactSnapshotWriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAkH/C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,gBAAgB,EAAE,iBAAiB,GAAG,UAAU,CAyBxF"}
|
|
@@ -57,12 +57,9 @@ function writeTreeSectionCore(treesNode, snapshotTree) {
|
|
|
57
57
|
if (snapshotTree.unreferenced) {
|
|
58
58
|
(0, zipItDataRepresentationUtils_1.addBoolProperty)(treeNode, "unreferenced", snapshotTree.unreferenced);
|
|
59
59
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const childNode = treeNode.addNode("list");
|
|
64
|
-
writeTreeSectionCore(childNode, value);
|
|
65
|
-
}
|
|
60
|
+
treeNode.addString("children", true);
|
|
61
|
+
const childNode = treeNode.addNode("list");
|
|
62
|
+
writeTreeSectionCore(childNode, value);
|
|
66
63
|
}
|
|
67
64
|
if (snapshotTree.blobs) {
|
|
68
65
|
for (const [path, id] of Object.entries(snapshotTree.blobs)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.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 { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n // Only write children prop if either blobs or trees are present.\n if (Object.keys(value.blobs).length > 0 || Object.keys(value.trees).length > 0) {\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"compactSnapshotWriter.js","sourceRoot":"","sources":["../src/compactSnapshotWriter.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 { assert, stringToBuffer } from \"@fluidframework/common-utils\";\nimport { IBlob, ISequencedDocumentMessage, ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { snapshotMinReadVersion } from \"./compactSnapshotParser\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { TreeBuilderSerializer } from \"./WriteBufferUtils\";\nimport { addBoolProperty, addNumberProperty, addStringProperty, NodeCore } from \"./zipItDataRepresentationUtils\";\n\n/**\n * Writes header section of the snapshot.\n * @param node - snapshot node to serialize to\n * @param latestSequenceNumber - latest seq number of the container.\n*/\nfunction writeSnapshotProps(node: NodeCore, latestSequenceNumber: number) {\n addStringProperty(node, \"mrv\", snapshotMinReadVersion);\n addStringProperty(node, \"cv\", snapshotMinReadVersion);\n addNumberProperty(node, \"lsn\", latestSequenceNumber);\n}\n\n/**\n * Represents blobs in the tree.\n * @param snapshotNode - node to serialize to.\n * @param blobs - blobs that is being serialized\n*/\nfunction writeBlobsSection(snapshotNode: NodeCore, blobs: Map<string, IBlob | ArrayBuffer>) {\n snapshotNode.addString(\"blobs\", true);\n const blobsNode = snapshotNode.addNode(\"list\");\n for (const [storageBlobId, blob] of blobs) {\n const blobNode = blobsNode.addNode();\n addStringProperty(blobNode, \"id\", storageBlobId, true);\n blobNode.addString(\"data\", true);\n if (blob instanceof ArrayBuffer) {\n blobNode.addBlob(new Uint8Array(blob), false);\n } else {\n blobNode.addBlob(new Uint8Array(stringToBuffer(blob.contents, blob.encoding ?? \"utf-8\")), false);\n }\n }\n}\n\n/**\n * Represents and serializes tree part of the snapshot\n * @param snapshotNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n*/\nfunction writeTreeSection(snapshotNode: NodeCore, snapshotTree: ISnapshotTree) {\n snapshotNode.addString(\"treeNodes\", true);\n const treesNode = snapshotNode.addNode(\"list\");\n writeTreeSectionCore(treesNode, snapshotTree);\n}\n\nfunction writeTreeSectionCore(treesNode: NodeCore, snapshotTree: ISnapshotTree) {\n for (const [path, value] of Object.entries(snapshotTree.trees)) {\n const treeNode = treesNode.addNode();\n addStringProperty(treeNode, \"name\", path);\n if (snapshotTree.unreferenced) {\n addBoolProperty(treeNode, \"unreferenced\", snapshotTree.unreferenced);\n }\n treeNode.addString(\"children\", true);\n const childNode = treeNode.addNode(\"list\");\n writeTreeSectionCore(childNode, value);\n }\n\n if (snapshotTree.blobs) {\n for (const [path, id] of Object.entries(snapshotTree.blobs)) {\n const blobNode = treesNode.addNode();\n addStringProperty(blobNode, \"name\", path);\n addStringProperty(blobNode, \"value\", id, true);\n }\n }\n}\n\n/**\n * Represents (serializes) snapshot tree as generalizes tree\n * @param rootNode - tree node to serialize to\n * @param snapshotTree - snapshot tree that is being serialized\n * @param blobs - blobs mapping of the snapshot\n * @param snapshotSequenceNumber - seq number at which snapshot is taken\n*/\nfunction writeSnapshotSection(\n rootNode: NodeCore,\n snapshotTree: ISnapshotTree,\n snapshotSequenceNumber: number,\n) {\n rootNode.addString(\"snapshot\", true);\n const snapshotNode = rootNode.addNode();\n\n const snapshotId = snapshotTree.id;\n assert(snapshotId !== undefined, 0x21b /* \"Snapshot id should be provided\" */);\n addStringProperty(snapshotNode, \"id\", snapshotId);\n addStringProperty(snapshotNode, \"message\", `Snapshot@${snapshotSequenceNumber}`);\n addNumberProperty(snapshotNode, \"sequenceNumber\", snapshotSequenceNumber);\n\n // Add Trees\n writeTreeSection(snapshotNode, snapshotTree);\n}\n\n/**\n * Represents ops in the tree.\n * @param rootNode - node to serialize to.\n * @param ops - ops that is being serialized\n*/\nfunction writeOpsSection(rootNode: NodeCore, ops: ISequencedDocumentMessage[]) {\n let firstSequenceNumber: number | undefined;\n if (ops.length > 0) {\n firstSequenceNumber = ops[0].sequenceNumber;\n }\n if (firstSequenceNumber !== undefined) {\n rootNode.addString(\"deltas\", true);\n const opsNode = rootNode.addNode();\n addNumberProperty(opsNode, \"firstSequenceNumber\", firstSequenceNumber);\n opsNode.addString(\"deltas\", true);\n const deltaNode = opsNode.addNode(\"list\");\n ops.forEach((op) => {\n deltaNode.addString(JSON.stringify(op), false);\n });\n }\n}\n\n/**\n * Converts trees/blobs/ops to binary compact representation.\n * @param snapshotContents - snapshot tree contents to serialize\n * @returns - ReadBuffer - binary representation of the data.\n */\nexport function convertToCompactSnapshot(snapshotContents: ISnapshotContents): ReadBuffer {\n const builder = new TreeBuilderSerializer();\n // Create the root node.\n const rootNode = builder.addNode();\n assert(snapshotContents.sequenceNumber !== undefined, 0x21c /* \"Seq number should be provided\" */);\n\n const latestSequenceNumber = snapshotContents.latestSequenceNumber ??\n snapshotContents.ops.length > 0 ?\n snapshotContents.ops[snapshotContents.ops.length - 1].sequenceNumber : snapshotContents.sequenceNumber;\n\n writeSnapshotProps(rootNode, latestSequenceNumber);\n\n writeSnapshotSection(\n rootNode,\n snapshotContents.snapshotTree,\n snapshotContents.sequenceNumber,\n );\n\n // Add Blobs\n writeBlobsSection(rootNode, snapshotContents.blobs);\n\n // Then write the ops node.\n writeOpsSection(rootNode, snapshotContents.ops);\n\n return builder.serialize();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAItE,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAClC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAAE,aAAa,EAAwB,wBAAwB,EAA8B,MAAM,aAAa,CAAC;AAGxH,OAAO,EAKH,aAAa,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAItD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,oBAAY,yBAAyB;IACjC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAC/B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;CAAE,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAC9G,OAAO,CAAC,iBAAiB,CAAC,CAwB5B;AAED,wBAAsB,uBAAuB,CACzC,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EAAE,+BAA+B,EACpD,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CAChB,oBAAoB,EAAE,gBAAgB,EACtC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,eAAe,KAC3B,OAAO,CAAC,kCAAkC,CAAC,EAChD,UAAU,EAAE,CAAC,cAAc,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAClC,oBAAoB,CAAC,EAAE,OAAO,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAsD5B;
|
|
1
|
+
{"version":3,"file":"fetchSnapshot.d.ts","sourceRoot":"","sources":["../src/fetchSnapshot.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAItE,OAAO,EACH,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAClC,MAAM,yCAAyC,CAAC;AAGjD,OAAO,EAAE,aAAa,EAAwB,wBAAwB,EAA8B,MAAM,aAAa,CAAC;AAGxH,OAAO,EAKH,aAAa,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAItD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C;;GAEG;AACH,oBAAY,yBAAyB;IACjC,IAAI,IAAI;IACR,MAAM,IAAI;IACV,aAAa,IAAI;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAC/B,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,OAAO,EAC1B,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE;IAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;CAAE,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAC9G,OAAO,CAAC,iBAAiB,CAAC,CAwB5B;AAED,wBAAsB,uBAAuB,CACzC,eAAe,EAAE,gBAAgB,EACjC,mBAAmB,EAAE,+BAA+B,EACpD,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,sCAAsC,EAAE,OAAO,EAC/C,MAAM,EAAE,gBAAgB,EACxB,kBAAkB,EAAE,CAChB,oBAAoB,EAAE,gBAAgB,EACtC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,UAAU,CAAC,EAAE,eAAe,KAC3B,OAAO,CAAC,kCAAkC,CAAC,EAChD,UAAU,EAAE,CAAC,cAAc,EAAE,wBAAwB,KAAK,OAAO,CAAC,IAAI,CAAC,EACvE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAClC,oBAAoB,CAAC,EAAE,OAAO,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAsD5B;AAwRD,MAAM,WAAW,kCAAkC;IAC/C,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE;QAAE,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC;KAAE,CAAC;CAC7C;AAiDD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,QAK5D;AAWD;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAClC,eAAe,EAAE,gBAAgB,EACjC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,gBAAgB,EACxB,eAAe,EAAE,gBAAgB,GAAG,SAAS,EAC7C,uBAAuB,CAAC,EAAE,yBAAyB,EACnD,UAAU,CAAC,EAAE,eAAe,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,YAAY,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,kCAAkC,CAAC,CA0C7C"}
|
package/dist/fetchSnapshot.js
CHANGED
|
@@ -138,20 +138,19 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
|
|
|
138
138
|
const response = await snapshotDownloader(odspResolvedUrl, storageToken, snapshotOptions, controller);
|
|
139
139
|
const odspResponse = response.odspResponse;
|
|
140
140
|
const contentType = odspResponse.headers.get("content-type");
|
|
141
|
-
|
|
141
|
+
// Measure how much time we spend processing payload
|
|
142
|
+
const snapshotParseEvent = telemetry_utils_1.PerformanceEvent.start(logger, {
|
|
143
|
+
eventName: "SnapshotParse",
|
|
144
|
+
driverVersion: packageVersion_1.pkgVersion,
|
|
145
|
+
contentType,
|
|
146
|
+
});
|
|
147
|
+
const propsToLog = Object.assign(Object.assign({}, odspResponse.propsToLog), { contentType, accept: response.requestHeaders.accept, driverVersion: packageVersion_1.pkgVersion });
|
|
142
148
|
let parsedSnapshotContents;
|
|
143
|
-
let contentTypeToRead;
|
|
144
|
-
if ((contentType === null || contentType === void 0 ? void 0 : contentType.indexOf("application/ms-fluid")) !== -1) {
|
|
145
|
-
contentTypeToRead = "application/ms-fluid";
|
|
146
|
-
}
|
|
147
|
-
else if ((contentType === null || contentType === void 0 ? void 0 : contentType.indexOf("application/json")) !== -1) {
|
|
148
|
-
contentTypeToRead = "application/json";
|
|
149
|
-
}
|
|
150
149
|
try {
|
|
151
|
-
switch (
|
|
150
|
+
switch (contentType) {
|
|
152
151
|
case "application/json": {
|
|
153
152
|
const text = await odspResponse.content.text();
|
|
154
|
-
|
|
153
|
+
propsToLog.bodySize = text.length;
|
|
155
154
|
const content = JSON.parse(text);
|
|
156
155
|
validateBlobsAndTrees(content);
|
|
157
156
|
const snapshotContents = (0, odspSnapshotParser_1.convertOdspSnapshotToSnapshotTreeAndBlobs)(content);
|
|
@@ -160,29 +159,30 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
|
|
|
160
159
|
}
|
|
161
160
|
case "application/ms-fluid": {
|
|
162
161
|
const content = await odspResponse.content.arrayBuffer();
|
|
163
|
-
|
|
162
|
+
propsToLog.bodySize = content.byteLength;
|
|
164
163
|
const snapshotContents = (0, compactSnapshotParser_1.parseCompactSnapshotResponse)(new ReadBufferUtils_1.ReadBuffer(new Uint8Array(content)));
|
|
165
164
|
if (snapshotContents.snapshotTree.trees === undefined ||
|
|
166
165
|
snapshotContents.snapshotTree.blobs === undefined) {
|
|
167
|
-
throw new driver_utils_1.NonRetryableError("Returned odsp snapshot is malformed. No trees or blobs!", driver_definitions_1.DriverErrorType.incorrectServerResponse,
|
|
166
|
+
throw new driver_utils_1.NonRetryableError("Returned odsp snapshot is malformed. No trees or blobs!", driver_definitions_1.DriverErrorType.incorrectServerResponse, propsToLog);
|
|
168
167
|
}
|
|
169
168
|
parsedSnapshotContents = Object.assign(Object.assign({}, odspResponse), { content: snapshotContents });
|
|
170
169
|
break;
|
|
171
170
|
}
|
|
172
171
|
default:
|
|
173
|
-
throw new driver_utils_1.NonRetryableError("Unknown snapshot content type", driver_definitions_1.DriverErrorType.incorrectServerResponse,
|
|
172
|
+
throw new driver_utils_1.NonRetryableError("Unknown snapshot content type", driver_definitions_1.DriverErrorType.incorrectServerResponse, propsToLog);
|
|
174
173
|
}
|
|
175
174
|
}
|
|
176
175
|
catch (error) {
|
|
177
176
|
if ((0, telemetry_utils_1.isFluidError)(error)) {
|
|
178
|
-
error.addTelemetryProperties(
|
|
177
|
+
error.addTelemetryProperties(propsToLog);
|
|
179
178
|
throw error;
|
|
180
179
|
}
|
|
181
|
-
const enhancedError = (0, telemetry_utils_1.wrapError)(error, (errorMessage) => new driver_utils_1.NonRetryableError(`Error parsing snapshot response: ${errorMessage}`, driver_definitions_1.DriverErrorType.genericError,
|
|
180
|
+
const enhancedError = (0, telemetry_utils_1.wrapError)(error, (errorMessage) => new driver_utils_1.NonRetryableError(`Error parsing snapshot response: ${errorMessage}`, driver_definitions_1.DriverErrorType.genericError, propsToLog));
|
|
182
181
|
throw enhancedError;
|
|
183
182
|
}
|
|
184
183
|
(0, common_utils_1.assert)(parsedSnapshotContents !== undefined, 0x312 /* snapshot should be parsed */);
|
|
185
184
|
const snapshot = parsedSnapshotContents.content;
|
|
185
|
+
const { trees, numBlobs, encodedBlobsSize } = evalBlobsAndTrees(snapshot);
|
|
186
186
|
// From: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming
|
|
187
187
|
// fetchStart: immediately before the browser starts to fetch the resource.
|
|
188
188
|
// requestStart: immediately before the browser starts requesting the resource from the server
|
|
@@ -233,7 +233,6 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
|
|
|
233
233
|
break;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
-
const { numTrees, numBlobs, encodedBlobsSize } = evalBlobsAndTrees(parsedSnapshotContents.content);
|
|
237
236
|
// There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we
|
|
238
237
|
// cannot cache using an HTTP response header.
|
|
239
238
|
const canCache = odspResponse.headers.get("disablebrowsercachingofusercontent") !== "true";
|
|
@@ -258,7 +257,8 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
|
|
|
258
257
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
259
258
|
putInCache(valueWithEpoch);
|
|
260
259
|
}
|
|
261
|
-
|
|
260
|
+
snapshotParseEvent.end();
|
|
261
|
+
event.end(Object.assign({ trees, blobs: (_e = (_d = snapshot.blobs) === null || _d === void 0 ? void 0 : _d.size) !== null && _e !== void 0 ? _e : 0, leafNodes: numBlobs, encodedBlobsSize,
|
|
262
262
|
sequenceNumber, ops: (_g = (_f = snapshot.ops) === null || _f === void 0 ? void 0 : _f.length) !== null && _g !== void 0 ? _g : 0, userOps: (_j = (_h = snapshot.ops) === null || _h === void 0 ? void 0 : _h.filter((op) => (0, driver_utils_1.isRuntimeMessage)(op)).length) !== null && _j !== void 0 ? _j : 0, headers: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,
|
|
263
263
|
// Interval between the first fetch until the last byte of the last redirect.
|
|
264
264
|
redirectTime,
|
|
@@ -281,7 +281,7 @@ async function fetchLatestSnapshotCore(odspResolvedUrl, storageTokenFetcher, sna
|
|
|
281
281
|
// Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,
|
|
282
282
|
// Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate
|
|
283
283
|
// if the permission has changed.
|
|
284
|
-
sltelemetry: odspResponse.headers.get("x-fluid-sltelemetry") },
|
|
284
|
+
sltelemetry: odspResponse.headers.get("x-fluid-sltelemetry") }, propsToLog));
|
|
285
285
|
return snapshot;
|
|
286
286
|
}).catch((error) => {
|
|
287
287
|
// We hit these errors in stress tests, under load
|
|
@@ -327,13 +327,13 @@ function getFormBodyAndHeaders(odspResolvedUrl, storageToken, snapshotOptions, h
|
|
|
327
327
|
return { body: postBody, headers: header };
|
|
328
328
|
}
|
|
329
329
|
function evalBlobsAndTrees(snapshot) {
|
|
330
|
-
const
|
|
330
|
+
const trees = countTreesInSnapshotTree(snapshot.snapshotTree);
|
|
331
331
|
const numBlobs = snapshot.blobs.size;
|
|
332
332
|
let encodedBlobsSize = 0;
|
|
333
333
|
for (const [_, blobContent] of snapshot.blobs) {
|
|
334
334
|
encodedBlobsSize += blobContent.byteLength;
|
|
335
335
|
}
|
|
336
|
-
return {
|
|
336
|
+
return { trees, numBlobs, encodedBlobsSize };
|
|
337
337
|
}
|
|
338
338
|
function validateBlobsAndTrees(snapshot) {
|
|
339
339
|
(0, common_utils_1.assert)(snapshot.trees !== undefined, 0x200 /* "Returned odsp snapshot is malformed. No trees!" */);
|
|
@@ -382,12 +382,14 @@ async function downloadSnapshot(odspResolvedUrl, storageToken, logger, snapshotO
|
|
|
382
382
|
};
|
|
383
383
|
// Decide what snapshot format to fetch as per the feature gate.
|
|
384
384
|
switch (snapshotFormatFetchType) {
|
|
385
|
+
case SnapshotFormatSupportType.JsonAndBinary:
|
|
386
|
+
headers.accept = `application/json, application/ms-fluid; v=${compactSnapshotParser_1.currentReadVersion}`;
|
|
387
|
+
break;
|
|
385
388
|
case SnapshotFormatSupportType.Binary:
|
|
386
389
|
headers.accept = `application/ms-fluid; v=${compactSnapshotParser_1.currentReadVersion}`;
|
|
387
390
|
break;
|
|
388
391
|
default:
|
|
389
|
-
|
|
390
|
-
headers.accept = `application/json, application/ms-fluid; v=${compactSnapshotParser_1.currentReadVersion}`;
|
|
392
|
+
headers.accept = "application/json";
|
|
391
393
|
}
|
|
392
394
|
const odspResponse = await ((_a = epochTracker === null || epochTracker === void 0 ? void 0 : epochTracker.fetch(url, fetchOptions, "treesLatest", true, scenarioName)) !== null && _a !== void 0 ? _a : (0, odspUtils_1.fetchHelper)(url, fetchOptions));
|
|
393
395
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSnapshot.js","sourceRoot":"","sources":["../src/fetchSnapshot.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 { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, fromUtf8ToBase64, performance } from \"@fluidframework/common-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { isFluidError, PerformanceEvent, wrapError } from \"@fluidframework/telemetry-utils\";\nimport {\n IOdspResolvedUrl,\n ISnapshotOptions,\n OdspErrorType,\n InstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { isRuntimeMessage, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IOdspSnapshot, ISnapshotCachedEntry, IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n fetchAndParseAsJSONHelper,\n fetchHelper,\n getWithRetryForTokenRefresh,\n getWithRetryForTokenRefreshRepeat,\n IOdspResponse,\n} from \"./odspUtils\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser\";\nimport { currentReadVersion, parseCompactSnapshotResponse } from \"./compactSnapshotParser\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { pkgVersion } from \"./packageVersion\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n Json = 0,\n Binary = 1,\n JsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n snapshotUrl: string,\n token: string | null,\n versionId: string,\n fetchFullSnapshot: boolean,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n const path = `/trees/${versionId}`;\n let queryParams: ISnapshotOptions = {};\n\n if (fetchFullSnapshot) {\n if (versionId !== \"latest\") {\n queryParams = { channels: 1, blobs: 2 };\n } else {\n queryParams = { deltas: 1, channels: 1, blobs: 2 };\n }\n }\n\n const queryString = getQueryString(queryParams);\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);\n const response = await PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"fetchSnapshot\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n },\n async () => snapshotDownloader(url, { headers }),\n ) as IOdspResponse<IOdspSnapshot>;\n return convertOdspSnapshotToSnapshotTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n removeEntries: () => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n return fetchLatestSnapshotCore(\n odspResolvedUrl,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n enableRedeemFallback,\n ).catch(async (error) => {\n if (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n // Execute the redeem fallback\n logger.sendErrorEvent({\n eventName: \"RedeemFallback\",\n errorType: error.errorType,\n }, error);\n await redeemSharingLink(\n odspResolvedUrl, storageTokenFetcher, logger, forceAccessTokenViaAuthorizationHeader);\n const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl =\n {\n ...odspResolvedUrl,\n shareLinkInfo: {\n ...odspResolvedUrl.shareLinkInfo,\n sharingLinkToRedeem: undefined,\n },\n };\n\n return fetchLatestSnapshotCore(\n odspResolvedUrlWithoutShareLink,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n );\n } else {\n throw error;\n }\n }).catch(async (error) => {\n // Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n // have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n // snapshot from cache in the future.\n if (typeof error === \"object\" && error !== null && error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n await removeEntries();\n }\n throw error;\n });\n}\n\nasync function redeemSharingLink(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n) {\n return PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"RedeemShareLink\",\n },\n async () => getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n assert(!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n 0x1ed /* \"Share link should be present\" */);\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"RedeemShareLink\");\n const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem);\n const redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n const { url, headers } = getUrlAndHeadersWithAuth(\n redeemUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers.prefer = \"redeemSharingLink\";\n return fetchAndParseAsJSONHelper(url, { headers });\n }),\n );\n}\n\nasync function fetchLatestSnapshotCore(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n return getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n assert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n let controller: AbortController | undefined;\n if (snapshotOptions?.timeout !== undefined) {\n controller = new AbortController();\n setTimeout(\n () => controller!.abort(),\n snapshotOptions.timeout,\n );\n }\n const perfEvent = {\n eventName: \"TreesLatest\",\n attempts: tokenFetchOptions.refresh ? 2 : 1,\n shareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n isSummarizer: odspResolvedUrl.summarizer,\n redeemFallbackEnabled: enableRedeemFallback,\n };\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n perfEvent[`snapshotOption_${key}`] = value;\n }\n });\n }\n // This event measures only successful cases of getLatest call (no tokens, no retries).\n return PerformanceEvent.timedExecAsync(\n logger,\n perfEvent,\n async (event) => {\n const response = await snapshotDownloader(\n odspResolvedUrl,\n storageToken,\n snapshotOptions,\n controller,\n );\n const odspResponse = response.odspResponse;\n const contentType = odspResponse.headers.get(\"content-type\");\n odspResponse.propsToLog = {\n ...odspResponse.propsToLog,\n contentType,\n accept: response.requestHeaders.accept,\n };\n let parsedSnapshotContents: IOdspResponse<ISnapshotContents> | undefined;\n let contentTypeToRead: string | undefined;\n if (contentType?.indexOf(\"application/ms-fluid\") !== -1) {\n contentTypeToRead = \"application/ms-fluid\";\n } else if (contentType?.indexOf(\"application/json\") !== -1) {\n contentTypeToRead = \"application/json\";\n }\n\n try {\n switch (contentTypeToRead) {\n case \"application/json\": {\n const text = await odspResponse.content.text();\n odspResponse.propsToLog.bodySize = text.length;\n const content: IOdspSnapshot = JSON.parse(text);\n validateBlobsAndTrees(content);\n const snapshotContents: ISnapshotContents =\n convertOdspSnapshotToSnapshotTreeAndBlobs(content);\n parsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n break;\n }\n case \"application/ms-fluid\": {\n const content = await odspResponse.content.arrayBuffer();\n odspResponse.propsToLog.bodySize = content.byteLength;\n const snapshotContents: ISnapshotContents = parseCompactSnapshotResponse(\n new ReadBuffer(new Uint8Array(content)));\n if (snapshotContents.snapshotTree.trees === undefined ||\n snapshotContents.snapshotTree.blobs === undefined) {\n throw new NonRetryableError(\n \"Returned odsp snapshot is malformed. No trees or blobs!\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion: pkgVersion, ...odspResponse.propsToLog },\n );\n }\n parsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n break;\n }\n default:\n throw new NonRetryableError(\n \"Unknown snapshot content type\",\n DriverErrorType.incorrectServerResponse,\n { driverVersion: pkgVersion, ...odspResponse.propsToLog },\n );\n }\n } catch (error) {\n if (isFluidError(error)) {\n error.addTelemetryProperties({ driverVersion: pkgVersion, ...odspResponse.propsToLog });\n throw error;\n }\n const enhancedError = wrapError(\n error,\n (errorMessage) => new NonRetryableError(\n `Error parsing snapshot response: ${errorMessage}`,\n DriverErrorType.genericError,\n { driverVersion: pkgVersion, ...odspResponse.propsToLog }));\n throw enhancedError;\n }\n assert(parsedSnapshotContents !== undefined, 0x312 /* snapshot should be parsed */);\n const snapshot = parsedSnapshotContents.content;\n // From: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming\n // fetchStart: immediately before the browser starts to fetch the resource.\n // requestStart: immediately before the browser starts requesting the resource from the server\n // responseStart: immediately after the browser receives the first byte of the response from the server.\n // responseEnd: immediately after the browser receives the last byte of the resource\n // or immediately before the transport connection is closed, whichever comes first.\n // secureConnectionStart: immediately before the browser starts the handshake process to secure the\n // current connection. If a secure connection is not used, this property returns zero.\n // startTime: Time when the resource fetch started. This value is equivalent to fetchStart.\n // domainLookupStart: immediately before the browser starts the domain name lookup for the resource.\n // domainLookupEnd: immediately after the browser finishes the domain name lookup for the resource.\n // redirectStart: start time of the fetch which that initiates the redirect.\n // redirectEnd: immediately after receiving the last byte of the response of the last redirect.\n let dnsLookupTime: number | undefined; // domainLookupEnd - domainLookupStart\n let redirectTime: number | undefined; // redirectEnd - redirectStart\n let tcpHandshakeTime: number | undefined; // connectEnd - connectStart\n let secureConnectionTime: number | undefined; // connectEnd - secureConnectionStart\n let responseNetworkTime: number | undefined; // responsEnd - responseStart\n let fetchStartToResponseEndTime: number | undefined; // responseEnd - fetchStart\n let reqStartToResponseEndTime: number | undefined; // responseEnd - requestStart\n let networkTime: number | undefined; // responseEnd - startTime\n const spReqDuration = odspResponse.headers.get(\"sprequestduration\");\n\n // getEntriesByType is only available in browser performance object\n const resources1 = performance.getEntriesByType?.(\"resource\") ?? [];\n // Usually the latest fetch call is to the end of resources, so we start from the end.\n for (let i = resources1.length - 1; i > 0; i--) {\n const indResTime = resources1[i] as PerformanceResourceTiming;\n const resource_name = indResTime.name;\n const resource_initiatortype = indResTime.initiatorType;\n if ((resource_initiatortype.localeCompare(\"fetch\") === 0)\n && (resource_name.localeCompare(response.requestUrl) === 0)) {\n redirectTime = indResTime.redirectEnd - indResTime.redirectStart;\n dnsLookupTime = indResTime.domainLookupEnd - indResTime.domainLookupStart;\n tcpHandshakeTime = indResTime.connectEnd - indResTime.connectStart;\n secureConnectionTime = (indResTime.secureConnectionStart > 0) ?\n (indResTime.connectEnd - indResTime.secureConnectionStart) : undefined;\n responseNetworkTime = (indResTime.responseStart > 0) ?\n (indResTime.responseEnd - indResTime.responseStart) : undefined;\n fetchStartToResponseEndTime = (indResTime.fetchStart > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n reqStartToResponseEndTime = (indResTime.requestStart > 0) ?\n (indResTime.responseEnd - indResTime.requestStart) : undefined;\n networkTime = (indResTime.startTime > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n if (spReqDuration !== undefined && networkTime !== undefined) {\n networkTime = networkTime - parseInt(spReqDuration, 10);\n }\n break;\n }\n }\n\n const { numTrees, numBlobs, encodedBlobsSize } =\n evalBlobsAndTrees(parsedSnapshotContents.content);\n\n // There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n // cannot cache using an HTTP response header.\n const canCache =\n odspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n const sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n const seqNumberFromOps = snapshot.ops && snapshot.ops.length > 0 ?\n snapshot.ops[0].sequenceNumber - 1 :\n undefined;\n\n if (!Number.isInteger(sequenceNumber)\n || seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber) {\n logger.sendErrorEvent({ eventName: \"fetchSnapshotError\", sequenceNumber, seqNumberFromOps });\n snapshot.sequenceNumber = undefined;\n } else if (canCache) {\n const fluidEpoch = odspResponse.headers.get(\"x-fluid-epoch\");\n assert(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n const value: ISnapshotCachedEntry = {\n ...snapshot,\n cacheEntryTime: Date.now(),\n };\n const valueWithEpoch: IVersionedValueWithEpoch = {\n value,\n fluidEpoch,\n version: persistedCacheValueVersion,\n };\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n putInCache(valueWithEpoch);\n }\n event.end({\n trees: numTrees,\n blobs: snapshot.blobs?.size ?? 0,\n leafNodes: numBlobs,\n encodedBlobsSize,\n sequenceNumber,\n ops: snapshot.ops?.length ?? 0,\n userOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n headers: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n // Interval between the first fetch until the last byte of the last redirect.\n redirectTime,\n // Interval between start and finish of the domain name lookup for the resource.\n dnsLookupTime,\n // Interval to receive all (first to last) bytes form the server.\n responseNetworkTime,\n // Time to establish the connection to the server to retrieve the resource.\n tcpHandshakeTime,\n // Time from the end of the connection until the inital handshake process to secure the connection.\n secureConnectionTime,\n // Interval between the initial fetch until the last byte is received.\n fetchStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte.\n reqStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte but\n // excluding the Snaphot request duration indicated on the snapshot response header.\n networkTime,\n // Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n // Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n // Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n // if the permission has changed.\n sltelemetry: odspResponse.headers.get(\"x-fluid-sltelemetry\"),\n ...odspResponse.propsToLog,\n });\n return snapshot;\n },\n ).catch((error) => {\n // We hit these errors in stress tests, under load\n // It's useful to try one more time in such case.\n if (typeof error === \"object\" && error !== null && (error.errorType === DriverErrorType.fetchFailure ||\n error.errorType === OdspErrorType.fetchTimeout)) {\n error[getWithRetryForTokenRefreshRepeat] = true;\n }\n throw error;\n });\n });\n}\n\nexport interface ISnapshotRequestAndResponseOptions {\n odspResponse: IOdspResponse<Response>;\n requestUrl: string;\n requestHeaders: { [index: string]: any; };\n}\n\nfunction getFormBodyAndHeaders(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n headers?: { [index: string]: string; },\n) {\n const formBoundary = uuid();\n const formParams: string[] = [];\n formParams.push(`--${formBoundary}`);\n formParams.push(`Authorization: Bearer ${storageToken}`);\n formParams.push(`X-HTTP-Method-Override: GET`);\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (headers !== undefined) {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n formParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n }\n formParams.push(`_post: 1`);\n formParams.push(`\\r\\n--${formBoundary}--`);\n const postBody = formParams.join(\"\\r\\n\");\n const header: { [index: string]: any; } = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n return { body: postBody, headers: header };\n}\n\nfunction evalBlobsAndTrees(snapshot: ISnapshotContents) {\n const numTrees = countTreesInSnapshotTree(snapshot.snapshotTree);\n const numBlobs = snapshot.blobs.size;\n let encodedBlobsSize = 0;\n for (const [_, blobContent] of snapshot.blobs) {\n encodedBlobsSize += blobContent.byteLength;\n }\n return { numTrees, numBlobs, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot) {\n assert(snapshot.trees !== undefined,\n 0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */);\n assert(snapshot.blobs !== undefined,\n 0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */);\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n let numTrees = 0;\n for (const [_, tree] of Object.entries(snapshotTree.trees)) {\n numTrees += 1;\n numTrees += countTreesInSnapshotTree(tree);\n }\n return numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n logger: ITelemetryLogger,\n snapshotOptions: ISnapshotOptions | undefined,\n snapshotFormatFetchType?: SnapshotFormatSupportType,\n controller?: AbortController,\n epochTracker?: EpochTracker,\n scenarioName?: string,\n): Promise<ISnapshotRequestAndResponseOptions> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n const snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n const url = `${snapshotUrl}/trees/latest?ump=1`;\n // The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n // Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n // This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n // for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n const header = { prefer: \"manualredirect\" };\n const { body, headers } = getFormBodyAndHeaders(\n odspResolvedUrl, storageToken, snapshotOptions, header);\n const fetchOptions = {\n body,\n headers,\n signal: controller?.signal,\n method: \"POST\",\n };\n // Decide what snapshot format to fetch as per the feature gate.\n switch (snapshotFormatFetchType) {\n case SnapshotFormatSupportType.Binary:\n headers.accept = `application/ms-fluid; v=${currentReadVersion}`;\n break;\n default:\n // By default ask both versions and let the server decide the format.\n headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n }\n\n const odspResponse = await (epochTracker?.fetch(url, fetchOptions, \"treesLatest\", true, scenarioName) ??\n fetchHelper(url, fetchOptions));\n\n return {\n odspResponse,\n requestHeaders: headers,\n requestUrl: url,\n };\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n && (typeof error === \"object\" && error !== null)\n && (error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)) {\n return true;\n }\n return false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n /**\n * Encode the url to accepted format by Sharepoint\n * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n */\n let encodedUrl = fromUtf8ToBase64(encodeURI(url));\n encodedUrl = encodedUrl\n .replace(/=+$/g, \"\")\n .replace(/\\//g, \"_\")\n .replace(/\\+/g, \"-\");\n encodedUrl = \"u!\".concat(encodedUrl);\n return encodedUrl;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"fetchSnapshot.js","sourceRoot":"","sources":["../src/fetchSnapshot.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 { default as AbortController } from \"abort-controller\";\nimport { v4 as uuid } from \"uuid\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { assert, fromUtf8ToBase64, performance } from \"@fluidframework/common-utils\";\nimport { DriverErrorType } from \"@fluidframework/driver-definitions\";\nimport { isFluidError, PerformanceEvent, wrapError } from \"@fluidframework/telemetry-utils\";\nimport {\n IOdspResolvedUrl,\n ISnapshotOptions,\n OdspErrorType,\n InstrumentedStorageTokenFetcher,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { DriverErrorTelemetryProps, isRuntimeMessage, NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { IOdspSnapshot, ISnapshotCachedEntry, IVersionedValueWithEpoch, persistedCacheValueVersion } from \"./contracts\";\nimport { getQueryString } from \"./getQueryString\";\nimport { getUrlAndHeadersWithAuth } from \"./getUrlAndHeadersWithAuth\";\nimport {\n fetchAndParseAsJSONHelper,\n fetchHelper,\n getWithRetryForTokenRefresh,\n getWithRetryForTokenRefreshRepeat,\n IOdspResponse,\n} from \"./odspUtils\";\nimport { ISnapshotContents } from \"./odspPublicUtils\";\nimport { convertOdspSnapshotToSnapshotTreeAndBlobs } from \"./odspSnapshotParser\";\nimport { currentReadVersion, parseCompactSnapshotResponse } from \"./compactSnapshotParser\";\nimport { ReadBuffer } from \"./ReadBufferUtils\";\nimport { EpochTracker } from \"./epochTracker\";\nimport { pkgVersion } from \"./packageVersion\";\n\n/**\n * Enum to support different types of snapshot formats.\n */\nexport enum SnapshotFormatSupportType {\n Json = 0,\n Binary = 1,\n JsonAndBinary = 2,\n}\n\n/**\n * Fetches a snapshot from the server with a given version id.\n * @param snapshotUrl - snapshot url from where the odsp snapshot will be fetched\n * @param token - token used for authorization in the request\n * @param storageFetchWrapper - Implementation of the get/post methods used to fetch the snapshot\n * @param versionId - id of specific snapshot to be fetched\n * @param fetchFullSnapshot - whether we want to fetch full snapshot(with blobs)\n * @param forceAccessTokenViaAuthorizationHeader - whether to force passing given token via authorization header\n * @returns A promise of the snapshot and the status code of the response\n */\nexport async function fetchSnapshot(\n snapshotUrl: string,\n token: string | null,\n versionId: string,\n fetchFullSnapshot: boolean,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (url: string, fetchOptions: { [index: string]: any; }) => Promise<IOdspResponse<unknown>>,\n): Promise<ISnapshotContents> {\n const path = `/trees/${versionId}`;\n let queryParams: ISnapshotOptions = {};\n\n if (fetchFullSnapshot) {\n if (versionId !== \"latest\") {\n queryParams = { channels: 1, blobs: 2 };\n } else {\n queryParams = { deltas: 1, channels: 1, blobs: 2 };\n }\n }\n\n const queryString = getQueryString(queryParams);\n const { url, headers } = getUrlAndHeadersWithAuth(\n `${snapshotUrl}${path}${queryString}`, token, forceAccessTokenViaAuthorizationHeader);\n const response = await PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"fetchSnapshot\",\n headers: Object.keys(headers).length !== 0 ? true : undefined,\n },\n async () => snapshotDownloader(url, { headers }),\n ) as IOdspResponse<IOdspSnapshot>;\n return convertOdspSnapshotToSnapshotTreeAndBlobs(response.content);\n}\n\nexport async function fetchSnapshotWithRedeem(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n forceAccessTokenViaAuthorizationHeader: boolean,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n removeEntries: () => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n return fetchLatestSnapshotCore(\n odspResolvedUrl,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n enableRedeemFallback,\n ).catch(async (error) => {\n if (enableRedeemFallback && isRedeemSharingLinkError(odspResolvedUrl, error)) {\n // Execute the redeem fallback\n logger.sendErrorEvent({\n eventName: \"RedeemFallback\",\n errorType: error.errorType,\n }, error);\n await redeemSharingLink(\n odspResolvedUrl, storageTokenFetcher, logger, forceAccessTokenViaAuthorizationHeader);\n const odspResolvedUrlWithoutShareLink: IOdspResolvedUrl =\n {\n ...odspResolvedUrl,\n shareLinkInfo: {\n ...odspResolvedUrl.shareLinkInfo,\n sharingLinkToRedeem: undefined,\n },\n };\n\n return fetchLatestSnapshotCore(\n odspResolvedUrlWithoutShareLink,\n storageTokenFetcher,\n snapshotOptions,\n logger,\n snapshotDownloader,\n putInCache,\n );\n } else {\n throw error;\n }\n }).catch(async (error) => {\n // Clear the cache on 401/403/404 on snapshot fetch from network because this means either the user doesn't\n // have permissions for the file or it was deleted. So, if we do not clear cache, we will continue fetching\n // snapshot from cache in the future.\n if (typeof error === \"object\" && error !== null && error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError) {\n await removeEntries();\n }\n throw error;\n });\n}\n\nasync function redeemSharingLink(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n logger: ITelemetryLogger,\n forceAccessTokenViaAuthorizationHeader: boolean,\n) {\n return PerformanceEvent.timedExecAsync(\n logger,\n {\n eventName: \"RedeemShareLink\",\n },\n async () => getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n assert(!!odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem,\n 0x1ed /* \"Share link should be present\" */);\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"RedeemShareLink\");\n const encodedShareUrl = getEncodedShareUrl(odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem);\n const redeemUrl = `${odspResolvedUrl.siteUrl}/_api/v2.0/shares/${encodedShareUrl}`;\n const { url, headers } = getUrlAndHeadersWithAuth(\n redeemUrl, storageToken, forceAccessTokenViaAuthorizationHeader);\n headers.prefer = \"redeemSharingLink\";\n return fetchAndParseAsJSONHelper(url, { headers });\n }),\n );\n}\n\nasync function fetchLatestSnapshotCore(\n odspResolvedUrl: IOdspResolvedUrl,\n storageTokenFetcher: InstrumentedStorageTokenFetcher,\n snapshotOptions: ISnapshotOptions | undefined,\n logger: ITelemetryLogger,\n snapshotDownloader: (\n finalOdspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n controller?: AbortController,\n ) => Promise<ISnapshotRequestAndResponseOptions>,\n putInCache: (valueWithEpoch: IVersionedValueWithEpoch) => Promise<void>,\n enableRedeemFallback?: boolean,\n): Promise<ISnapshotContents> {\n return getWithRetryForTokenRefresh(async (tokenFetchOptions) => {\n const storageToken = await storageTokenFetcher(tokenFetchOptions, \"TreesLatest\", true);\n assert(storageToken !== null, 0x1e5 /* \"Storage token should not be null\" */);\n\n let controller: AbortController | undefined;\n if (snapshotOptions?.timeout !== undefined) {\n controller = new AbortController();\n setTimeout(\n () => controller!.abort(),\n snapshotOptions.timeout,\n );\n }\n const perfEvent = {\n eventName: \"TreesLatest\",\n attempts: tokenFetchOptions.refresh ? 2 : 1,\n shareLinkPresent: odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined,\n isSummarizer: odspResolvedUrl.summarizer,\n redeemFallbackEnabled: enableRedeemFallback,\n };\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n perfEvent[`snapshotOption_${key}`] = value;\n }\n });\n }\n // This event measures only successful cases of getLatest call (no tokens, no retries).\n return PerformanceEvent.timedExecAsync(\n logger,\n perfEvent,\n async (event) => {\n const response = await snapshotDownloader(\n odspResolvedUrl,\n storageToken,\n snapshotOptions,\n controller,\n );\n\n const odspResponse = response.odspResponse;\n const contentType = odspResponse.headers.get(\"content-type\");\n\n // Measure how much time we spend processing payload\n const snapshotParseEvent = PerformanceEvent.start(logger, {\n eventName: \"SnapshotParse\",\n driverVersion: pkgVersion,\n contentType,\n });\n\n const propsToLog: DriverErrorTelemetryProps = {\n ...odspResponse.propsToLog,\n contentType,\n accept: response.requestHeaders.accept,\n driverVersion: pkgVersion,\n };\n let parsedSnapshotContents: IOdspResponse<ISnapshotContents> | undefined;\n\n try {\n switch (contentType) {\n case \"application/json\": {\n const text = await odspResponse.content.text();\n propsToLog.bodySize = text.length;\n const content: IOdspSnapshot = JSON.parse(text);\n validateBlobsAndTrees(content);\n const snapshotContents: ISnapshotContents =\n convertOdspSnapshotToSnapshotTreeAndBlobs(content);\n parsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n break;\n }\n case \"application/ms-fluid\": {\n const content = await odspResponse.content.arrayBuffer();\n propsToLog.bodySize = content.byteLength;\n const snapshotContents: ISnapshotContents = parseCompactSnapshotResponse(\n new ReadBuffer(new Uint8Array(content)));\n if (snapshotContents.snapshotTree.trees === undefined ||\n snapshotContents.snapshotTree.blobs === undefined) {\n throw new NonRetryableError(\n \"Returned odsp snapshot is malformed. No trees or blobs!\",\n DriverErrorType.incorrectServerResponse,\n propsToLog,\n );\n }\n parsedSnapshotContents = { ...odspResponse, content: snapshotContents };\n break;\n }\n default:\n throw new NonRetryableError(\n \"Unknown snapshot content type\",\n DriverErrorType.incorrectServerResponse,\n propsToLog,\n );\n }\n } catch (error) {\n if (isFluidError(error)) {\n error.addTelemetryProperties(propsToLog);\n throw error;\n }\n const enhancedError = wrapError(\n error,\n (errorMessage) => new NonRetryableError(\n `Error parsing snapshot response: ${errorMessage}`,\n DriverErrorType.genericError,\n propsToLog));\n throw enhancedError;\n }\n\n assert(parsedSnapshotContents !== undefined, 0x312 /* snapshot should be parsed */);\n const snapshot = parsedSnapshotContents.content;\n const { trees, numBlobs, encodedBlobsSize } = evalBlobsAndTrees(snapshot);\n\n // From: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming\n // fetchStart: immediately before the browser starts to fetch the resource.\n // requestStart: immediately before the browser starts requesting the resource from the server\n // responseStart: immediately after the browser receives the first byte of the response from the server.\n // responseEnd: immediately after the browser receives the last byte of the resource\n // or immediately before the transport connection is closed, whichever comes first.\n // secureConnectionStart: immediately before the browser starts the handshake process to secure the\n // current connection. If a secure connection is not used, this property returns zero.\n // startTime: Time when the resource fetch started. This value is equivalent to fetchStart.\n // domainLookupStart: immediately before the browser starts the domain name lookup for the resource.\n // domainLookupEnd: immediately after the browser finishes the domain name lookup for the resource.\n // redirectStart: start time of the fetch which that initiates the redirect.\n // redirectEnd: immediately after receiving the last byte of the response of the last redirect.\n let dnsLookupTime: number | undefined; // domainLookupEnd - domainLookupStart\n let redirectTime: number | undefined; // redirectEnd - redirectStart\n let tcpHandshakeTime: number | undefined; // connectEnd - connectStart\n let secureConnectionTime: number | undefined; // connectEnd - secureConnectionStart\n let responseNetworkTime: number | undefined; // responsEnd - responseStart\n let fetchStartToResponseEndTime: number | undefined; // responseEnd - fetchStart\n let reqStartToResponseEndTime: number | undefined; // responseEnd - requestStart\n let networkTime: number | undefined; // responseEnd - startTime\n const spReqDuration = odspResponse.headers.get(\"sprequestduration\");\n\n // getEntriesByType is only available in browser performance object\n const resources1 = performance.getEntriesByType?.(\"resource\") ?? [];\n // Usually the latest fetch call is to the end of resources, so we start from the end.\n for (let i = resources1.length - 1; i > 0; i--) {\n const indResTime = resources1[i] as PerformanceResourceTiming;\n const resource_name = indResTime.name;\n const resource_initiatortype = indResTime.initiatorType;\n if ((resource_initiatortype.localeCompare(\"fetch\") === 0)\n && (resource_name.localeCompare(response.requestUrl) === 0)) {\n redirectTime = indResTime.redirectEnd - indResTime.redirectStart;\n dnsLookupTime = indResTime.domainLookupEnd - indResTime.domainLookupStart;\n tcpHandshakeTime = indResTime.connectEnd - indResTime.connectStart;\n secureConnectionTime = (indResTime.secureConnectionStart > 0) ?\n (indResTime.connectEnd - indResTime.secureConnectionStart) : undefined;\n responseNetworkTime = (indResTime.responseStart > 0) ?\n (indResTime.responseEnd - indResTime.responseStart) : undefined;\n fetchStartToResponseEndTime = (indResTime.fetchStart > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n reqStartToResponseEndTime = (indResTime.requestStart > 0) ?\n (indResTime.responseEnd - indResTime.requestStart) : undefined;\n networkTime = (indResTime.startTime > 0) ?\n (indResTime.responseEnd - indResTime.fetchStart) : undefined;\n if (spReqDuration !== undefined && networkTime !== undefined) {\n networkTime = networkTime - parseInt(spReqDuration, 10);\n }\n break;\n }\n }\n\n // There are some scenarios in ODSP where we cannot cache, trees/latest will explicitly tell us when we\n // cannot cache using an HTTP response header.\n const canCache =\n odspResponse.headers.get(\"disablebrowsercachingofusercontent\") !== \"true\";\n const sequenceNumber: number = snapshot.sequenceNumber ?? 0;\n const seqNumberFromOps = snapshot.ops && snapshot.ops.length > 0 ?\n snapshot.ops[0].sequenceNumber - 1 :\n undefined;\n\n if (!Number.isInteger(sequenceNumber)\n || seqNumberFromOps !== undefined && seqNumberFromOps !== sequenceNumber) {\n logger.sendErrorEvent({ eventName: \"fetchSnapshotError\", sequenceNumber, seqNumberFromOps });\n snapshot.sequenceNumber = undefined;\n } else if (canCache) {\n const fluidEpoch = odspResponse.headers.get(\"x-fluid-epoch\");\n assert(fluidEpoch !== undefined, 0x1e6 /* \"Epoch should be present in response\" */);\n const value: ISnapshotCachedEntry = {\n ...snapshot,\n cacheEntryTime: Date.now(),\n };\n const valueWithEpoch: IVersionedValueWithEpoch = {\n value,\n fluidEpoch,\n version: persistedCacheValueVersion,\n };\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n putInCache(valueWithEpoch);\n }\n\n snapshotParseEvent.end();\n\n event.end({\n trees,\n blobs: snapshot.blobs?.size ?? 0,\n leafNodes: numBlobs,\n encodedBlobsSize,\n sequenceNumber,\n ops: snapshot.ops?.length ?? 0,\n userOps: snapshot.ops?.filter((op) => isRuntimeMessage(op)).length ?? 0,\n headers: Object.keys(response.requestHeaders).length !== 0 ? true : undefined,\n // Interval between the first fetch until the last byte of the last redirect.\n redirectTime,\n // Interval between start and finish of the domain name lookup for the resource.\n dnsLookupTime,\n // Interval to receive all (first to last) bytes form the server.\n responseNetworkTime,\n // Time to establish the connection to the server to retrieve the resource.\n tcpHandshakeTime,\n // Time from the end of the connection until the inital handshake process to secure the connection.\n secureConnectionTime,\n // Interval between the initial fetch until the last byte is received.\n fetchStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte.\n reqStartToResponseEndTime,\n // Interval between starting the request for the resource until receiving the last byte but\n // excluding the Snaphot request duration indicated on the snapshot response header.\n networkTime,\n // Sharing link telemetry regarding sharing link redeem status and performance. Ex: FRL; dur=100,\n // Azure Fluid Relay service; desc=S, FRP; desc=False. Here, FRL is the duration taken for redeem,\n // Azure Fluid Relay service is the redeem status (S means success), and FRP is a flag to indicate\n // if the permission has changed.\n sltelemetry: odspResponse.headers.get(\"x-fluid-sltelemetry\"),\n ...propsToLog,\n });\n return snapshot;\n },\n ).catch((error) => {\n // We hit these errors in stress tests, under load\n // It's useful to try one more time in such case.\n if (typeof error === \"object\" && error !== null && (error.errorType === DriverErrorType.fetchFailure ||\n error.errorType === OdspErrorType.fetchTimeout)) {\n error[getWithRetryForTokenRefreshRepeat] = true;\n }\n throw error;\n });\n });\n}\n\nexport interface ISnapshotRequestAndResponseOptions {\n odspResponse: IOdspResponse<Response>;\n requestUrl: string;\n requestHeaders: { [index: string]: any; };\n}\n\nfunction getFormBodyAndHeaders(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n snapshotOptions: ISnapshotOptions | undefined,\n headers?: { [index: string]: string; },\n) {\n const formBoundary = uuid();\n const formParams: string[] = [];\n formParams.push(`--${formBoundary}`);\n formParams.push(`Authorization: Bearer ${storageToken}`);\n formParams.push(`X-HTTP-Method-Override: GET`);\n if (snapshotOptions !== undefined) {\n Object.entries(snapshotOptions).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (headers !== undefined) {\n Object.entries(headers).forEach(([key, value]) => {\n if (value !== undefined) {\n formParams.push(`${key}: ${value}`);\n }\n });\n }\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem) {\n formParams.push(`sl: ${odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem}`);\n }\n formParams.push(`_post: 1`);\n formParams.push(`\\r\\n--${formBoundary}--`);\n const postBody = formParams.join(\"\\r\\n\");\n const header: { [index: string]: any; } = {\n \"Content-Type\": `multipart/form-data;boundary=${formBoundary}`,\n };\n return { body: postBody, headers: header };\n}\n\nfunction evalBlobsAndTrees(snapshot: ISnapshotContents) {\n const trees = countTreesInSnapshotTree(snapshot.snapshotTree);\n const numBlobs = snapshot.blobs.size;\n let encodedBlobsSize = 0;\n for (const [_, blobContent] of snapshot.blobs) {\n encodedBlobsSize += blobContent.byteLength;\n }\n return { trees, numBlobs, encodedBlobsSize };\n}\n\nexport function validateBlobsAndTrees(snapshot: IOdspSnapshot) {\n assert(snapshot.trees !== undefined,\n 0x200 /* \"Returned odsp snapshot is malformed. No trees!\" */);\n assert(snapshot.blobs !== undefined,\n 0x201 /* \"Returned odsp snapshot is malformed. No blobs!\" */);\n}\n\nfunction countTreesInSnapshotTree(snapshotTree: ISnapshotTree): number {\n let numTrees = 0;\n for (const [_, tree] of Object.entries(snapshotTree.trees)) {\n numTrees += 1;\n numTrees += countTreesInSnapshotTree(tree);\n }\n return numTrees;\n}\n\n/**\n * This function fetches the snapshot and parse it according to what is mentioned in response headers.\n * @param odspResolvedUrl - resolved odsp url.\n * @param storageToken - token to do the auth for network request.\n * @param snapshotOptions - Options used to specify how and what to fetch in the snapshot.\n * @param logger - logger\n * @param snapshotFormatFetchType - Snapshot format to fetch.\n * @param controller - abort controller if caller needs to abort the network call.\n * @param epochTracker - epoch tracker used to add/validate epoch in the network call.\n * @returns fetched snapshot.\n */\nexport async function downloadSnapshot(\n odspResolvedUrl: IOdspResolvedUrl,\n storageToken: string,\n logger: ITelemetryLogger,\n snapshotOptions: ISnapshotOptions | undefined,\n snapshotFormatFetchType?: SnapshotFormatSupportType,\n controller?: AbortController,\n epochTracker?: EpochTracker,\n scenarioName?: string,\n): Promise<ISnapshotRequestAndResponseOptions> {\n // back-compat: This block to be removed with #8784 when we only consume/consider odsp resolvers that are >= 0.51\n const sharingLinkToRedeem = (odspResolvedUrl as any).sharingLinkToRedeem;\n if (sharingLinkToRedeem) {\n odspResolvedUrl.shareLinkInfo = { ...odspResolvedUrl.shareLinkInfo, sharingLinkToRedeem };\n }\n\n const snapshotUrl = odspResolvedUrl.endpoints.snapshotStorageUrl;\n const url = `${snapshotUrl}/trees/latest?ump=1`;\n // The location of file can move on Spo in which case server returns 308(Permanent Redirect) error.\n // Adding below header will make VROOM API return 404 instead of 308 and browser can intercept it.\n // This error thrown by server will contain the new redirect location. Look at the 404 error parsing\n // for futher reference here: \\packages\\utils\\odsp-doclib-utils\\src\\odspErrorUtils.ts\n const header = { prefer: \"manualredirect\" };\n const { body, headers } = getFormBodyAndHeaders(\n odspResolvedUrl, storageToken, snapshotOptions, header);\n const fetchOptions = {\n body,\n headers,\n signal: controller?.signal,\n method: \"POST\",\n };\n // Decide what snapshot format to fetch as per the feature gate.\n switch (snapshotFormatFetchType) {\n case SnapshotFormatSupportType.JsonAndBinary:\n headers.accept = `application/json, application/ms-fluid; v=${currentReadVersion}`;\n break;\n case SnapshotFormatSupportType.Binary:\n headers.accept = `application/ms-fluid; v=${currentReadVersion}`;\n break;\n default:\n headers.accept = \"application/json\";\n }\n\n const odspResponse = await (epochTracker?.fetch(url, fetchOptions, \"treesLatest\", true, scenarioName) ??\n fetchHelper(url, fetchOptions));\n\n return {\n odspResponse,\n requestHeaders: headers,\n requestUrl: url,\n };\n}\n\nfunction isRedeemSharingLinkError(odspResolvedUrl: IOdspResolvedUrl, error: any) {\n if (odspResolvedUrl.shareLinkInfo?.sharingLinkToRedeem !== undefined\n && (typeof error === \"object\" && error !== null)\n && (error.errorType === DriverErrorType.authorizationError\n || error.errorType === DriverErrorType.fileNotFoundOrAccessDeniedError)) {\n return true;\n }\n return false;\n}\n\nfunction getEncodedShareUrl(url: string): string {\n /**\n * Encode the url to accepted format by Sharepoint\n * https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/shares_get\n */\n let encodedUrl = fromUtf8ToBase64(encodeURI(url));\n encodedUrl = encodedUrl\n .replace(/=+$/g, \"\")\n .replace(/\\//g, \"_\")\n .replace(/\\+/g, \"-\");\n encodedUrl = \"u!\".concat(encodedUrl);\n return encodedUrl;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileLink.d.ts","sourceRoot":"","sources":["../src/getFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAKtE,OAAO,EACH,aAAa,EACb,6BAA6B,EAC7B,YAAY,EACZ,YAAY,EACf,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"getFileLink.d.ts","sourceRoot":"","sources":["../src/getFileLink.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAKtE,OAAO,EACH,aAAa,EACb,6BAA6B,EAC7B,YAAY,EACZ,YAAY,EACf,MAAM,yCAAyC,CAAC;AASjD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,WAAW,CAC7B,QAAQ,EAAE,YAAY,CAAC,6BAA6B,CAAC,EACrD,YAAY,EAAE,aAAa,EAC3B,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
|