|
|
@ -6,6 +6,7 @@ class MetaRPCClient { |
|
|
|
constructor(connectionStream) { |
|
|
|
constructor(connectionStream) { |
|
|
|
this.connectionStream = connectionStream; |
|
|
|
this.connectionStream = connectionStream; |
|
|
|
this.notificationChannel = new SafeEventEmitter(); |
|
|
|
this.notificationChannel = new SafeEventEmitter(); |
|
|
|
|
|
|
|
this.uncaughtErrorChannel = new SafeEventEmitter(); |
|
|
|
this.requests = new Map(); |
|
|
|
this.requests = new Map(); |
|
|
|
this.connectionStream.on('data', this.handleResponse.bind(this)); |
|
|
|
this.connectionStream.on('data', this.handleResponse.bind(this)); |
|
|
|
this.connectionStream.on('end', this.close.bind(this)); |
|
|
|
this.connectionStream.on('end', this.close.bind(this)); |
|
|
@ -17,36 +18,49 @@ class MetaRPCClient { |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
onUncaughtError(handler) { |
|
|
|
|
|
|
|
this.uncaughtErrorChannel.addListener('error', (error) => { |
|
|
|
|
|
|
|
handler(error); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
close() { |
|
|
|
close() { |
|
|
|
this.notificationChannel.removeAllListeners(); |
|
|
|
this.notificationChannel.removeAllListeners(); |
|
|
|
|
|
|
|
this.uncaughtErrorChannel.removeAllListeners(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
handleResponse(data) { |
|
|
|
handleResponse(data) { |
|
|
|
const { id, result, error, method, params } = data; |
|
|
|
const { id, result, error, method, params } = data; |
|
|
|
|
|
|
|
const isNotification = id === undefined && error === undefined; |
|
|
|
const cb = this.requests.get(id); |
|
|
|
const cb = this.requests.get(id); |
|
|
|
|
|
|
|
|
|
|
|
if (method && params && id) { |
|
|
|
if (method && params && !isNotification) { |
|
|
|
// dont handle server-side to client-side requests
|
|
|
|
// dont handle server-side to client-side requests
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (method && params && !id) { |
|
|
|
if (method && params && isNotification) { |
|
|
|
// handle servier-side to client-side notification
|
|
|
|
// handle servier-side to client-side notification
|
|
|
|
this.notificationChannel.emit('notification', data); |
|
|
|
this.notificationChannel.emit('notification', data); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (!cb) { |
|
|
|
|
|
|
|
// not found in request list
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (error) { |
|
|
|
if (error) { |
|
|
|
const e = new EthereumRpcError(error.code, error.message, error.data); |
|
|
|
const e = new EthereumRpcError(error.code, error.message, error.data); |
|
|
|
// preserve the stack from serializeError
|
|
|
|
// preserve the stack from serializeError
|
|
|
|
e.stack = error.stack; |
|
|
|
e.stack = error.stack; |
|
|
|
|
|
|
|
if (cb) { |
|
|
|
this.requests.delete(id); |
|
|
|
this.requests.delete(id); |
|
|
|
cb(e); |
|
|
|
cb(e); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
this.uncaughtErrorChannel.emit('error', e); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!cb) { |
|
|
|
|
|
|
|
// not found in request list
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.requests.delete(id); |
|
|
|
this.requests.delete(id); |
|
|
|
|
|
|
|
|
|
|
|