import { assert , stringToBuffer } from "@fluidframework/common-utils" ; import { IBlob , ISequencedDocumentMessage , ISnapshotTree } from "@fluidframework/protocol-definitions" ; import { snapshotMinReadVersion } from "./compactSnapshotParser" ; import { ISnapshotContents } from "./odspUtils" ; import { ReadBuffer } from "./ReadBufferUtils" ; import { TreeBuilderSerializer } from "./WriteBufferUtils" ; import { addBoolProperty , addNumberProperty , addStringProperty , NodeCore } from "./zipItDataRepresentationUtils" ; param node param latestSequenceNumber function writeSnapshotProps ( node , latestSequenceNumber ) { addStringProperty ( node , "mrv" , snapshotMinReadVersion ) ; addStringProperty ( node , "cv" , snapshotMinReadVersion ) ; addNumberProperty ( node , "lsn" , latestSequenceNumber ) ; } param snapshotNode param blobs function writeBlobsSection ( snapshotNode , blobs ) { snapshotNode . addString ( "blobs" , true ) ; const blobsNode = snapshotNode . addNode ( "list" ) ; for ( const [ storageBlobId , blob ] of blobs ) { const blobNode = blobsNode . addNode ( ) ; addStringProperty ( blobNode , "id" , storageBlobId , true ) ; blobNode . addString ( "data" , true ) ; if ( blob instanceof ArrayBuffer ) { blobNode . addBlob ( new Uint8Array ( blob ) , false ) ; } else { blobNode . addBlob ( new Uint8Array ( stringToBuffer ( blob . contents , blob . encoding ?? "utf-8" ) ) , false ) ; } } } param snapshotNode param snapshotTree function writeTreeSection ( snapshotNode , snapshotTree ) { snapshotNode . addString ( "treeNodes" , true ) ; const treesNode = snapshotNode . addNode ( "list" ) ; writeTreeSectionCore ( treesNode , snapshotTree ) ; } function writeTreeSectionCore ( treesNode , snapshotTree ) { for ( const [ path , value ] of Object . entries ( snapshotTree . trees ) ) { const treeNode = treesNode . addNode ( ) ; addStringProperty ( treeNode , "name" , path ) ; if ( snapshotTree . unreferenced ) { addBoolProperty ( treeNode , "unreferenced" , snapshotTree . unreferenced ) ; } treeNode . addString ( "children" , true ) ; const childNode = treeNode . addNode ( "list" ) ; writeTreeSectionCore ( childNode , value ) ; } if ( snapshotTree . blobs ) { for ( const [ path , id ] of Object . entries ( snapshotTree . blobs ) ) { const blobNode = treesNode . addNode ( ) ; addStringProperty ( blobNode , "name" , path ) ; addStringProperty ( blobNode , "value" , id , true ) ; } } } param rootNode param snapshotTree param blobs param snapshotSequenceNumber function writeSnapshotSection ( rootNode , snapshotTree , snapshotSequenceNumber ) { rootNode . addString ( "snapshot" , true ) ; const snapshotNode = rootNode . addNode ( ) ; const snapshotId = snapshotTree . id ; assert ( snapshotId !== undefined , 0x21b ) ; addStringProperty ( snapshotNode , "id" , snapshotId ) ; addStringProperty ( snapshotNode , "message" , `Snapshot@${ snapshotSequenceNumber }` ) ; addNumberProperty ( snapshotNode , "sequenceNumber" , snapshotSequenceNumber ) ; writeTreeSection ( snapshotNode , snapshotTree ) ; } param rootNode param ops function writeOpsSection ( rootNode , ops ) { let firstSequenceNumber ; if ( ops . length > 0 ) { firstSequenceNumber = ops [ 0 ] . sequenceNumber ; } if ( firstSequenceNumber !== undefined ) { rootNode . addString ( "deltas" , true ) ; const opsNode = rootNode . addNode ( ) ; addNumberProperty ( opsNode , "firstSequenceNumber" , firstSequenceNumber ) ; opsNode . addString ( "deltas" , true ) ; const deltaNode = opsNode . addNode ( "list" ) ; ops . forEach ( ( op ) => { deltaNode . addString ( JSON . stringify ( op ) , false ) ; } ) ; } } param snapshotContents returns export function convertToCompactSnapshot ( snapshotContents ) { const builder = new TreeBuilderSerializer ( ) ; const rootNode = builder . addNode ( ) ; assert ( snapshotContents . sequenceNumber !== undefined , 0x21c ) ; const ops = snapshotContents . ops ; const latestSequenceNumber = ops . length > 0 ? ops [ ops . length - 1 ] . sequenceNumber : snapshotContents . sequenceNumber ; writeSnapshotProps ( rootNode , latestSequenceNumber ) ; writeSnapshotSection ( rootNode , snapshotContents . snapshotTree , snapshotContents . sequenceNumber ) ; writeBlobsSection ( rootNode , snapshotContents . blobs ) ; writeOpsSection ( rootNode , ops ) ; return builder . serialize ( ) ; }