11import ITransport from "./transports/Transport" ;
22
3- let id = 1 ;
4-
53interface IJSONRPCRequest {
64 jsonrpc : "2.0" ;
7- id : number ;
5+ id : string ;
86 method : string ;
97 params : any [ ] | object ;
108}
@@ -16,7 +14,7 @@ interface IJSONRPCError {
1614
1715interface IJSONRPCResponse {
1816 jsonrpc : "2.0" ;
19- id : number ;
17+ id : string ; // can also be null
2018 result ?: any ;
2119 error ?: IJSONRPCError ;
2220}
@@ -38,6 +36,7 @@ class RequestManager {
3836 private requests : any ;
3937 private batchStarted : boolean = false ;
4038 private batch : IJSONRPCRequest [ ] = [ ] ;
39+ private lastId : number = - 1 ;
4140
4241 constructor ( transports : ITransport [ ] ) {
4342 this . transports = transports ;
@@ -59,14 +58,15 @@ class RequestManager {
5958 }
6059
6160 public async request ( method : string , params : any ) : Promise < any > {
61+ const i = ( ++ this . lastId ) . toString ( ) ;
6262 return new Promise ( ( resolve , reject ) => {
63- const i = id ++ ;
6463 // naively grab first transport and use it
6564 const transport = this . transports [ 0 ] ;
6665 this . requests [ i ] = {
6766 resolve,
6867 reject,
6968 } ;
69+
7070 const payload : IJSONRPCRequest = {
7171 jsonrpc : "2.0" ,
7272 id : i ,
@@ -78,7 +78,7 @@ class RequestManager {
7878 } else {
7979 transport . sendData ( JSON . stringify ( payload ) ) ;
8080 }
81- } ) ;
81+ } ) . finally ( ( ) => this . requests [ i ] = undefined ) ;
8282 }
8383
8484 public close ( ) : void {
@@ -98,9 +98,6 @@ class RequestManager {
9898 this . batchStarted = true ;
9999 }
100100
101- /**
102- *
103- */
104101 public endBatch ( ) : void {
105102 if ( this . batchStarted === false ) {
106103 throw new Error ( "cannot end that which has never started" ) ;
@@ -117,34 +114,24 @@ class RequestManager {
117114
118115 private onData ( data : string ) : void {
119116 const parsedData : IJSONRPCResponse [ ] | IJSONRPCResponse = JSON . parse ( data ) ;
120- // handle batch requests
121- if ( Array . isArray ( parsedData ) ) {
122- parsedData . forEach ( ( response ) => {
123- if ( ! this . requests [ response . id ] ) {
124- return ;
125- }
126- if ( response . error ) {
127- this . requests [ response . id ] . reject ( response . error ) ;
128- } else {
129- this . requests [ response . id ] . resolve ( response . result ) ;
130- }
131- } ) ;
132- return ;
133- }
134- if ( typeof parsedData . result === "undefined" && typeof parsedData . error === "undefined" ) {
135- return ;
136- }
137- const req = this . requests [ parsedData . id ] ;
138- if ( req === undefined ) {
139- return ;
140- }
141- // resolve promise for id
142- if ( parsedData . error ) {
143- req . reject ( parsedData . error ) ;
144- } else {
145- req . resolve ( parsedData . result ) ;
146- }
147- delete this . requests [ parsedData . id ] ;
117+ const results = parsedData instanceof Array ? parsedData : [ parsedData ] ;
118+
119+ results . forEach ( ( response ) => {
120+ const promiseForResult = this . requests [ response . id ] ;
121+ if ( promiseForResult === undefined ) {
122+ throw new Error (
123+ `Received an unrecognized response id: ${ response . id } . Valid ids are: ${ Object . keys ( this . requests ) } ` ,
124+ ) ;
125+ }
126+
127+ if ( response . error ) {
128+ promiseForResult . reject ( response . error ) ;
129+ } else if ( response . result ) {
130+ promiseForResult . resolve ( response . result ) ;
131+ } else {
132+ throw new Error ( `Malformed JSON-RPC response object: ${ response } ` ) ;
133+ }
134+ } ) ;
148135 }
149136}
150137
0 commit comments