import { BlockMap } from "builder-util-runtime/out/blockMapApi"; import { close, fstat, open, read } from "fs-extra"; import { DifferentialDownloader } from "./DifferentialDownloader"; import { inflateRawSync } from "zlib"; export class FileWithEmbeddedBlockMapDifferentialDownloader extends DifferentialDownloader { async download(): Promise<void> { const packageInfo = this.blockAwareFileInfo; const fileSize = packageInfo.size!!; const offset = fileSize - (packageInfo.blockMapSize!! + 4); this.fileMetadataBuffer = await this.readRemoteBytes(offset, fileSize - 1); const newBlockMap = readBlockMap( this.fileMetadataBuffer.slice(0, this.fileMetadataBuffer.length - 4) ); const emit = () => {}; await this.doDownload( await readEmbeddedBlockMapData(this.options.oldFile), newBlockMap, emit ); } } function readBlockMap(data: Buffer): BlockMap { return JSON.parse(inflateRawSync(data).toString()); } async function readEmbeddedBlockMapData(file: string): Promise<BlockMap> { const fd = await open(file, "r"); try { const fileSize = (await fstat(fd)).size; const sizeBuffer = Buffer.allocUnsafe(4); await read( fd, sizeBuffer, 0, sizeBuffer.length, fileSize - sizeBuffer.length ); const dataBuffer = Buffer.allocUnsafe(sizeBuffer.readUInt32BE(0)); await read( fd, dataBuffer, 0, dataBuffer.length, fileSize - sizeBuffer.length - dataBuffer.length ); await close(fd); return readBlockMap(dataBuffer); } catch (e) { await close(fd); throw e; } }