import { Readable } from "readable-stream" ; import { CompressedJSON , Value } from "../quicktype-core/input/CompressedJSON" ; const { Parser } = require ( "stream-json" ) ; const methodMap = { startObject : "pushObjectContext" , endObject : "finishObject" , startArray : "pushArrayContext" , endArray : "finishArray" , startNumber : "handleStartNumber" , numberChunk : "handleNumberChunk" , endNumber : "handleEndNumber" , keyValue : "setPropertyKey" , stringValue : "commitString" , nullValue : "commitNull" , trueValue : "handleTrueValue" , falseValue : "handleFalseValue" } ; export class CompressedJSONFromStream extends CompressedJSON < Readable > { async parse ( readStream ) { const combo = new Parser ( { packKeys : true , packStrings : true } ) ; combo . on ( "data" , ( item ) => { if ( typeof methodMap [ item . name ] === "string" ) { ( this as any ) [ methodMap [ item . name ] ] ( item . value ) ; } } ) ; const promise = new Promise < Value > ( ( resolve , reject ) => { combo . on ( "end" , ( ) => { resolve ( this . finish ( ) ) ; } ) ; combo . on ( "error" , ( err ) => { reject ( err ) ; } ) ; } ) ; readStream . setEncoding ( "utf8" ) ; readStream . pipe ( combo ) ; readStream . resume ( ) ; return promise ; } protected handleStartNumber = ( ) : void => { this . pushContext ( ) ; this . context . currentNumberIsDouble = false ; } ; protected handleNumberChunk = ( s ) : void => { const ctx = this . context ; if ( ! ctx . currentNumberIsDouble && /[\.e]/i . test ( s ) ) { ctx . currentNumberIsDouble = true ; } } ; protected handleEndNumber ( ) { const isDouble = this . context . currentNumberIsDouble ; this . popContext ( ) ; this . commitNumber ( isDouble ) ; } protected handleTrueValue ( ) { this . commitBoolean ( true ) ; } protected handleFalseValue ( ) { this . commitBoolean ( false ) ; } }