feat: stream zip files to destination binary

This commit is contained in:
calebboyd
2023-04-02 12:06:26 -05:00
parent 5d5513d264
commit 7febbbd89d
3 changed files with 35 additions and 32 deletions
+27 -16
View File
@@ -16,9 +16,11 @@ import {
} from './util'
import { NexeOptions, version } from './options'
import { NexeTarget } from './target'
import { PassThrough, Readable, Stream, Transform } from 'stream'
import MultiStream = require('multistream')
import { Bundle, toStream } from './fs/bundle'
import { File } from 'resolve-dependencies'
import { FactoryStream, LazyStream } from 'multistream'
const isBsd = Boolean(~process.platform.indexOf('bsd'))
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make'
@@ -287,25 +289,34 @@ export class NexeCompiler {
return [this.shims.join(''), this.startup].join(';')
}
private async _assembleDeliverable(binary: NodeJS.ReadableStream) {
private async _assembleDeliverable(binary: Readable) {
if (!this.options.mangle) {
return binary
}
const launchCode = this.code()
const vfsStream = await this.bundle.toStream()
let vfsSize = 0
const vfsSum = new Transform({
transform(chunk, _enc, cb) {
chunk && (vfsSize += chunk.length)
cb(null, chunk)
},
})
const onEnd = new Promise<void>((resolve) => vfsSum.once('end', resolve))
const streams = [binary, toStream(launchCode), vfsStream.pipe(vfsSum)]
const code = this.code(),
codeSize = Buffer.byteLength(code),
lengths = Buffer.from(Array(16))
const bundleBuffer = await this.bundle.toBuffer()
lengths.writeDoubleLE(codeSize, 0)
lengths.writeDoubleLE(bundleBuffer.length, 8)
return new (MultiStream as any)([
binary,
toStream(code),
toStream(bundleBuffer),
toStream(Buffer.concat([Buffer.from('<nexe~~sentinel>'), lengths])),
])
let done = false
return new MultiStream(async (cb) => {
if (done) cb(null, null)
else if (streams.length) cb(null, streams.shift() as Readable)
else {
done = true
await onEnd
const trailers = Buffer.alloc(16)
trailers.writeDoubleLE(Buffer.byteLength(launchCode), 0)
trailers.writeDoubleLE(vfsSize, 8)
cb(null, toStream(Buffer.concat([Buffer.from('<nexe~~sentinel>'), trailers])))
}
})
}
}
+4 -13
View File
@@ -1,11 +1,7 @@
import * as fs from 'fs'
import { promisify } from 'util'
import { relative } from 'path'
import { Readable } from 'stream'
import { argv } from '../options'
import { File } from 'resolve-dependencies'
import MultiStream = require('multistream')
const archiver: any = require('archiver')
import archiver from 'archiver'
function makeRelativeToZip(cwd: string, path: string) {
return '/snapshot/' + relative(cwd, path)
@@ -45,13 +41,8 @@ export class Bundle {
}
}
public async toBuffer(): Promise<Buffer> {
this.zip.finalize()
const zipData: Buffer[] = []
this.zip.on('data', (data: Buffer) => zipData.push(data))
return await new Promise((resolve, reject) => {
this.zip.on('error', (error: Error) => reject(error))
this.zip.on('end', () => resolve(Buffer.concat(zipData)))
})
public async toStream(): Promise<Readable> {
await this.zip.finalize()
return this.zip
}
}
+4 -3
View File
@@ -1,14 +1,15 @@
const fs = require('fs'),
fd = fs.openSync(process.execPath, 'r'),
stat = fs.statSync(process.execPath),
tailSize = Math.min(stat.size, 16000),
tailSize = Math.min(stat.size, 4096),
tailWindow = Buffer.from(Array(tailSize))
fs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize)
const footerPosition = tailWindow.indexOf('<nexe~~sentinel>')
if (footerPosition == -1) {
throw 'Invalid Nexe binary'
if (footerPosition === -1) {
process.stderr.write('Invalid Nexe binary')
process.exit(1)
}
const footer = tailWindow.slice(footerPosition, footerPosition + 32),