@@ -112,19 +112,15 @@ function quoteString(string: string) {
112112
113113function readAsPromised ( stream : Readable , size ?) {
114114 const value = stream . read ( size ) ;
115- if ( value === null ) {
115+ if ( value === null && ! stream . readableEnded ) {
116116 return new Promise ( ( resolve , reject ) => {
117- if ( stream . readableEnded ) {
118- resolve ( null ) ;
119- return ;
120- }
121117 const endListener = ( ) => resolve ( null ) ;
122118 stream . once ( 'end' , endListener ) ;
123119 stream . once ( 'error' , reject ) ;
124120 stream . once ( 'readable' , ( ) => {
125121 stream . removeListener ( 'end' , endListener ) ;
126122 stream . removeListener ( 'error' , reject ) ;
127- resolve ( stream . read ( ) ) ;
123+ readAsPromised ( stream , size ) . then ( resolve , reject ) ;
128124 } ) ;
129125 } ) ;
130126 }
@@ -137,10 +133,11 @@ interface Item {
137133 value ?: any ;
138134 indent ?: string ;
139135 path ?: ( string | number ) [ ] ;
136+ type ?: string ;
140137}
141138
142139enum ReadState {
143- NotReading = 0 ,
140+ Inactive = 0 ,
144141 Reading ,
145142 ReadMore ,
146143 Consumed ,
@@ -278,17 +275,18 @@ export class JsonStreamStringify extends Readable {
278275 this . emit ( 'error' , new Error ( 'Readable Stream is in flowing mode, data may have been lost. Trying to pause stream.' ) , input , parent . path ) ;
279276 }
280277 const that = this ;
281- this . _push ( '"' ) ;
282- input . once ( 'end' , ( ) => {
283- this . _push ( '"' ) ;
284- this . item = parent ;
285- this . emit ( 'readable' ) ;
286- } ) ;
278+ this . prePush = '"' ;
287279 this . item = < any > {
288280 type : 'readable string' ,
289281 async read ( size : number ) {
290282 try {
291283 const data = await readAsPromised ( input , size ) ;
284+ if ( data === null ) {
285+ that . _push ( '"' ) ;
286+ that . item = parent ;
287+ that . unvisit ( input ) ;
288+ return ;
289+ }
292290 if ( data ) that . _push ( escapeString ( data . toString ( ) ) ) ;
293291 } catch ( err ) {
294292 that . emit ( 'error' , err ) ;
@@ -328,7 +326,7 @@ export class JsonStreamStringify extends Readable {
328326 if ( first ) first = false ;
329327 else out += ',' ;
330328 if ( that . indent ) out += `\n${ item . indent } ` ;
331- that . _push ( out ) ;
329+ that . prePush = out ;
332330 that . setItem ( data , item , i ) ;
333331 i += 1 ;
334332 } catch ( err ) {
@@ -448,15 +446,20 @@ export class JsonStreamStringify extends Readable {
448446 this . item = item ;
449447 }
450448
451- prePush ?: Function = undefined ;
452449 buffer = '' ;
453450 bufferLength = 0 ;
454451 pushCalled = false ;
455452
456453 readSize = 0 ;
454+ /** if set, this string will be prepended to the next _push call, if the call output is not empty, and set to undefined */
455+ prePush ?: string ;
457456 private _push ( data ) {
458- this . buffer += ( this . objectItem ? this . objectItem . write ( ) : '' ) + data ;
459- this . prePush = undefined ;
457+ const out = ( this . objectItem ? this . objectItem . write ( ) : '' ) + data ;
458+ if ( this . prePush && out . length ) {
459+ this . buffer += this . prePush ;
460+ this . prePush = undefined ;
461+ }
462+ this . buffer += out ;
460463 if ( this . buffer . length >= this . bufferSize ) {
461464 this . pushCalled = ! this . push ( this . buffer ) ;
462465 this . buffer = '' ;
@@ -466,10 +469,10 @@ export class JsonStreamStringify extends Readable {
466469 return true ;
467470 }
468471
469- readState : ReadState = ReadState . NotReading ;
470- async _read ( size ?: number ) {
472+ readState : ReadState = ReadState . Inactive ;
473+ async _read ( size ?: number ) : Promise < void > {
471474 if ( this . readState === ReadState . Consumed ) return ;
472- if ( this . readState !== ReadState . NotReading ) {
475+ if ( this . readState !== ReadState . Inactive ) {
473476 this . readState = ReadState . ReadMore ;
474477 return ;
475478 }
@@ -487,12 +490,14 @@ export class JsonStreamStringify extends Readable {
487490 this . push ( null ) ;
488491 this . readState = ReadState . Consumed ;
489492 this . cleanup ( ) ;
493+ return ;
490494 }
491495 if ( this . readState === < any > ReadState . ReadMore ) {
492- this . readState = ReadState . NotReading ;
493- this . _read ( size ) ;
496+ this . readState = ReadState . Inactive ;
497+ await this . _read ( size ) ;
498+ return ;
494499 }
495- this . readState = ReadState . NotReading ;
500+ this . readState = ReadState . Inactive ;
496501 }
497502
498503 private cleanup ( ) {
0 commit comments