@@ -112,19 +112,15 @@ function quoteString(string: string) {
112
112
113
113
function readAsPromised ( stream : Readable , size ?) {
114
114
const value = stream . read ( size ) ;
115
- if ( value === null ) {
115
+ if ( value === null && ! stream . readableEnded ) {
116
116
return new Promise ( ( resolve , reject ) => {
117
- if ( stream . readableEnded ) {
118
- resolve ( null ) ;
119
- return ;
120
- }
121
117
const endListener = ( ) => resolve ( null ) ;
122
118
stream . once ( 'end' , endListener ) ;
123
119
stream . once ( 'error' , reject ) ;
124
120
stream . once ( 'readable' , ( ) => {
125
121
stream . removeListener ( 'end' , endListener ) ;
126
122
stream . removeListener ( 'error' , reject ) ;
127
- resolve ( stream . read ( ) ) ;
123
+ readAsPromised ( stream , size ) . then ( resolve , reject ) ;
128
124
} ) ;
129
125
} ) ;
130
126
}
@@ -137,10 +133,11 @@ interface Item {
137
133
value ?: any ;
138
134
indent ?: string ;
139
135
path ?: ( string | number ) [ ] ;
136
+ type ?: string ;
140
137
}
141
138
142
139
enum ReadState {
143
- NotReading = 0 ,
140
+ Inactive = 0 ,
144
141
Reading ,
145
142
ReadMore ,
146
143
Consumed ,
@@ -278,17 +275,18 @@ export class JsonStreamStringify extends Readable {
278
275
this . emit ( 'error' , new Error ( 'Readable Stream is in flowing mode, data may have been lost. Trying to pause stream.' ) , input , parent . path ) ;
279
276
}
280
277
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 = '"' ;
287
279
this . item = < any > {
288
280
type : 'readable string' ,
289
281
async read ( size : number ) {
290
282
try {
291
283
const data = await readAsPromised ( input , size ) ;
284
+ if ( data === null ) {
285
+ that . _push ( '"' ) ;
286
+ that . item = parent ;
287
+ that . unvisit ( input ) ;
288
+ return ;
289
+ }
292
290
if ( data ) that . _push ( escapeString ( data . toString ( ) ) ) ;
293
291
} catch ( err ) {
294
292
that . emit ( 'error' , err ) ;
@@ -328,7 +326,7 @@ export class JsonStreamStringify extends Readable {
328
326
if ( first ) first = false ;
329
327
else out += ',' ;
330
328
if ( that . indent ) out += `\n${ item . indent } ` ;
331
- that . _push ( out ) ;
329
+ that . prePush = out ;
332
330
that . setItem ( data , item , i ) ;
333
331
i += 1 ;
334
332
} catch ( err ) {
@@ -448,15 +446,20 @@ export class JsonStreamStringify extends Readable {
448
446
this . item = item ;
449
447
}
450
448
451
- prePush ?: Function = undefined ;
452
449
buffer = '' ;
453
450
bufferLength = 0 ;
454
451
pushCalled = false ;
455
452
456
453
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 ;
457
456
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 ;
460
463
if ( this . buffer . length >= this . bufferSize ) {
461
464
this . pushCalled = ! this . push ( this . buffer ) ;
462
465
this . buffer = '' ;
@@ -466,10 +469,10 @@ export class JsonStreamStringify extends Readable {
466
469
return true ;
467
470
}
468
471
469
- readState : ReadState = ReadState . NotReading ;
470
- async _read ( size ?: number ) {
472
+ readState : ReadState = ReadState . Inactive ;
473
+ async _read ( size ?: number ) : Promise < void > {
471
474
if ( this . readState === ReadState . Consumed ) return ;
472
- if ( this . readState !== ReadState . NotReading ) {
475
+ if ( this . readState !== ReadState . Inactive ) {
473
476
this . readState = ReadState . ReadMore ;
474
477
return ;
475
478
}
@@ -487,12 +490,14 @@ export class JsonStreamStringify extends Readable {
487
490
this . push ( null ) ;
488
491
this . readState = ReadState . Consumed ;
489
492
this . cleanup ( ) ;
493
+ return ;
490
494
}
491
495
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 ;
494
499
}
495
- this . readState = ReadState . NotReading ;
500
+ this . readState = ReadState . Inactive ;
496
501
}
497
502
498
503
private cleanup ( ) {
0 commit comments