@@ -18,16 +18,18 @@ import 'utils.dart';
18
18
class Client {
19
19
final StreamChannel <dynamic > _channel;
20
20
21
- /// The next request id.
22
- var _id = 0 ;
21
+ /// A function to generate the next request id.
22
+ Object Function () _idGenerator ;
23
23
24
24
/// The current batch of requests to be sent together.
25
25
///
26
26
/// Each element is a JSON RPC spec compliant message.
27
27
List <Map <String , dynamic >>? _batch;
28
28
29
29
/// The map of request ids to pending requests.
30
- final _pendingRequests = < int , _Request > {};
30
+ ///
31
+ /// Keys must be of type `int` or `String` .
32
+ final _pendingRequests = < Object , _Request > {};
31
33
32
34
final _done = Completer <void >();
33
35
@@ -49,9 +51,14 @@ class Client {
49
51
///
50
52
/// Note that the client won't begin listening to [channel] until
51
53
/// [Client.listen] is called.
52
- Client (StreamChannel <String > channel)
54
+ ///
55
+ /// If [idGenerator] is passed, it will be called to generate an ID for each
56
+ /// request. Defaults to an auto-incrementing `int` . The value returned must
57
+ /// be either an `int` or `String` .
58
+ Client (StreamChannel <String > channel, {Object Function ()? idGenerator})
53
59
: this .withoutJson (
54
- jsonDocument.bind (channel).transformStream (ignoreFormatExceptions));
60
+ jsonDocument.bind (channel).transformStream (ignoreFormatExceptions),
61
+ idGenerator: idGenerator);
55
62
56
63
/// Creates a [Client] that communicates using decoded messages over
57
64
/// [_channel] .
@@ -61,7 +68,12 @@ class Client {
61
68
///
62
69
/// Note that the client won't begin listening to [_channel] until
63
70
/// [Client.listen] is called.
64
- Client .withoutJson (this ._channel) {
71
+ ///
72
+ /// If [_idGenerator] is passed, it will be called to generate an ID for each
73
+ /// request. Defaults to an auto-incrementing `int` . The value returned must
74
+ /// be either an `int` or `String` .
75
+ Client .withoutJson (this ._channel, {Object Function ()? idGenerator})
76
+ : _idGenerator = idGenerator ?? _createIncrementingIdGenerator () {
65
77
done.whenComplete (() {
66
78
for (var request in _pendingRequests.values) {
67
79
request.completer.completeError (StateError (
@@ -115,7 +127,7 @@ class Client {
115
127
/// Throws a [StateError] if the client is closed while the request is in
116
128
/// flight, or if the client is closed when this method is called.
117
129
Future <Object ?> sendRequest (String method, [Object ? parameters]) {
118
- var id = _id ++ ;
130
+ var id = _idGenerator () ;
119
131
_send (method, parameters, id);
120
132
121
133
var completer = Completer <Object ?>.sync ();
@@ -142,7 +154,7 @@ class Client {
142
154
///
143
155
/// Sends a request to invoke [method] with [parameters] . If [id] is given,
144
156
/// the request uses that id.
145
- void _send (String method, Object ? parameters, [int ? id]) {
157
+ void _send (String method, Object ? parameters, [Object ? id]) {
146
158
if (parameters is Iterable ) parameters = parameters.toList ();
147
159
if (parameters is ! Map && parameters is ! List && parameters != null ) {
148
160
throw ArgumentError ('Only maps and lists may be used as JSON-RPC '
@@ -201,7 +213,6 @@ class Client {
201
213
if (! _isResponseValid (response_)) return ;
202
214
final response = response_ as Map ;
203
215
var id = response['id' ];
204
- id = (id is String ) ? int .parse (id) : id;
205
216
var request = _pendingRequests.remove (id)! ;
206
217
if (response.containsKey ('result' )) {
207
218
request.completer.complete (response['result' ]);
@@ -218,7 +229,6 @@ class Client {
218
229
if (response is ! Map ) return false ;
219
230
if (response['jsonrpc' ] != '2.0' ) return false ;
220
231
var id = response['id' ];
221
- id = (id is String ) ? int .parse (id) : id;
222
232
if (! _pendingRequests.containsKey (id)) return false ;
223
233
if (response.containsKey ('result' )) return true ;
224
234
@@ -244,3 +254,11 @@ class _Request {
244
254
245
255
_Request (this .method, this .completer, this .chain);
246
256
}
257
+
258
+ /// The default ID generator, uses an auto incrementing integer.
259
+ ///
260
+ /// Each call returns a new function which starts back a `0` .
261
+ int Function () _createIncrementingIdGenerator () {
262
+ var nextId = 0 ;
263
+ return () => nextId++ ;
264
+ }
0 commit comments