@@ -40,6 +40,7 @@ Section -> Buffer
4040
4141// "wpc" + 1 in little-endian
4242const VERSION = 0x01637077 ;
43+ const _1GiB = 1 * 1024 * 1024 * 1024 ;
4344
4445/**
4546 * @param {Buffer[] } buffers buffers
@@ -87,7 +88,7 @@ const readUInt64LE = Buffer.prototype.readBigUInt64LE
8788 * @param {FileMiddleware } middleware this
8889 * @param {BufferSerializableType[] | Promise<BufferSerializableType[]> } data data to be serialized
8990 * @param {string | boolean } name file base name
90- * @param {function(string | false, Buffer[]): Promise<void> } writeFile writes a file
91+ * @param {function(string | false, Buffer[], number ): Promise<void> } writeFile writes a file
9192 * @param {string | Hash } hashFunction hash function to use
9293 * @returns {Promise<SerializeResult> } resulting file pointer and promise
9394 */
@@ -212,9 +213,9 @@ const serialize = async (
212213 if ( name === true ) {
213214 name = hashForName ( buf , hashFunction ) ;
214215 }
215- backgroundJobs . push ( writeFile ( name , buf ) ) ;
216216 let size = 0 ;
217217 for ( const b of buf ) size += b . length ;
218+ backgroundJobs . push ( writeFile ( name , buf , size ) ) ;
218219 return {
219220 size,
220221 name,
@@ -422,7 +423,7 @@ class FileMiddleware extends SerializerMiddleware {
422423 // It's important that we don't touch existing files during serialization
423424 // because serialize may read existing files (when deserializing)
424425 const allWrittenFiles = new Set ( ) ;
425- const writeFile = async ( name , content ) => {
426+ const writeFile = async ( name , content , size ) => {
426427 const file = name
427428 ? join ( this . fs , filename , `../${ name } ${ extension } ` )
428429 : filename ;
@@ -441,10 +442,7 @@ class FileMiddleware extends SerializerMiddleware {
441442 [ zConstants . BROTLI_PARAM_MODE ] : zConstants . BROTLI_MODE_TEXT ,
442443 [ zConstants . BROTLI_PARAM_QUALITY ] : 2 ,
443444 [ zConstants . BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING ] : true ,
444- [ zConstants . BROTLI_PARAM_SIZE_HINT ] : content . reduce (
445- ( size , b ) => size + b . length ,
446- 0
447- )
445+ [ zConstants . BROTLI_PARAM_SIZE_HINT ] : size
448446 }
449447 } ) ;
450448 }
@@ -456,8 +454,24 @@ class FileMiddleware extends SerializerMiddleware {
456454 stream . on ( "error" , err => reject ( err ) ) ;
457455 stream . on ( "finish" , ( ) => resolve ( ) ) ;
458456 }
459- for ( const b of content ) stream . write ( b ) ;
460- stream . end ( ) ;
457+ // use unsafe
458+ if ( size <= _1GiB ) {
459+ for ( const b of content ) stream . write ( b ) ;
460+ return stream . end ( ) ;
461+ }
462+
463+ const len = content . length ;
464+ let i = 0 ;
465+ const batchWrite = err => {
466+ if ( i === len ) {
467+ stream . end ( ) ;
468+ return ;
469+ }
470+ // will be handle in "on" handler
471+ if ( err ) return ;
472+ stream . write ( content [ i ++ ] , batchWrite ) ;
473+ } ;
474+ batchWrite ( ) ;
461475 } ) ;
462476 if ( name ) allWrittenFiles . add ( file ) ;
463477 } ;
0 commit comments