Skip to content

Commit

Permalink
Update lints, test JS & Wasm (#116)
Browse files Browse the repository at this point in the history
* Update lints, test JS & Wasm

* more bumps

* require dart 3.4
  • Loading branch information
kevmoo authored Jun 26, 2024
1 parent 5b1cbd6 commit 616937f
Show file tree
Hide file tree
Showing 18 changed files with 109 additions and 99 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
sdk: [2.19.0, dev]
sdk: [3.4, dev]
steps:
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
- uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30
Expand All @@ -59,3 +59,6 @@ jobs:
- name: Run VM tests
run: dart test --platform vm
if: always() && steps.install.outcome == 'success'
- name: Run browser tests
run: dart test --platform chrome --compiler dart2wasm,dart2js
if: always() && steps.install.outcome == 'success'
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 3.0.3-dev
## 3.0.3-wip

* Require Dart 2.19
* Require Dart 3.4

## 3.0.2

Expand Down
1 change: 0 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ linter:
- avoid_unused_constructor_parameters
- cancel_subscriptions
- package_api_docs
- test_types_in_equals
30 changes: 12 additions & 18 deletions lib/error_code.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

// ignore_for_file: constant_identifier_names

/// Error codes defined in the [JSON-RPC 2.0 specificiation][spec].
import 'src/exception.dart';

/// Error codes defined in the [JSON-RPC 2.0 specification][spec].
///
/// These codes are generally used for protocol-level communication. Most of
/// them shouldn't be used by the application. Those that should have
Expand Down Expand Up @@ -38,20 +40,12 @@ const SERVER_ERROR = -32000;
/// Returns a human-readable name for [errorCode] if it's one specified by the
/// JSON-RPC 2.0 spec.
///
/// If [errorCode] isn't defined in the JSON-RPC 2.0 spec, returns null.
String? name(int errorCode) {
switch (errorCode) {
case PARSE_ERROR:
return 'parse error';
case INVALID_REQUEST:
return 'invalid request';
case METHOD_NOT_FOUND:
return 'method not found';
case INVALID_PARAMS:
return 'invalid parameters';
case INTERNAL_ERROR:
return 'internal error';
default:
return null;
}
}
/// If [errorCode] isn't defined in the JSON-RPC 2.0 spec, returns `null`.
String? name(int errorCode) => switch (errorCode) {
PARSE_ERROR => 'parse error',
INVALID_REQUEST => 'invalid request',
METHOD_NOT_FOUND => 'method not found',
INVALID_PARAMS => 'invalid parameters',
INTERNAL_ERROR => 'internal error',
_ => null
};
26 changes: 14 additions & 12 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,19 @@ class Client {

/// Creates a [Client] that communicates over [channel].
///
/// Note that the client won't begin listening to [responses] until
/// Note that the client won't begin listening to [channel] until
/// [Client.listen] is called.
Client(StreamChannel<String> channel)
: this.withoutJson(
jsonDocument.bind(channel).transformStream(ignoreFormatExceptions));

/// Creates a [Client] that communicates using decoded messages over
/// [channel].
/// [_channel].
///
/// Unlike [Client.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the client won't begin listening to [responses] until
/// Note that the client won't begin listening to [_channel] until
/// [Client.listen] is called.
Client.withoutJson(this._channel) {
done.whenComplete(() {
Expand All @@ -80,7 +80,8 @@ class Client {
///
/// [listen] may only be called once.
Future listen() {
_channel.stream.listen(_handleResponse, onError: (error, stackTrace) {
_channel.stream.listen(_handleResponse,
onError: (Object error, StackTrace stackTrace) {
_done.completeError(error, stackTrace);
_channel.sink.close();
}, onDone: () {
Expand Down Expand Up @@ -113,11 +114,11 @@ class Client {
///
/// Throws a [StateError] if the client is closed while the request is in
/// flight, or if the client is closed when this method is called.
Future sendRequest(String method, [Object? parameters]) {
Future<Object?> sendRequest(String method, [Object? parameters]) {
var id = _id++;
_send(method, parameters, id);

var completer = Completer.sync();
var completer = Completer<Object?>.sync();
_pendingRequests[id] = _Request(method, completer, Chain.current());
return completer.future;
}
Expand All @@ -141,7 +142,7 @@ class Client {
///
/// Sends a request to invoke [method] with [parameters]. If [id] is given,
/// the request uses that id.
void _send(String method, parameters, [int? id]) {
void _send(String method, Object? parameters, [int? id]) {
if (parameters is Iterable) parameters = parameters.toList();
if (parameters is! Map && parameters is! List && parameters != null) {
throw ArgumentError('Only maps and lists may be used as JSON-RPC '
Expand Down Expand Up @@ -172,7 +173,7 @@ class Client {
/// If this is called in the context of another [withBatch] call, it just
/// invokes [callback] without creating another batch. This means that
/// responses are batched until the first batch ends.
void withBatch(Function() callback) {
void withBatch(FutureOr<void> Function() callback) {
if (_batch != null) {
callback();
return;
Expand All @@ -186,7 +187,7 @@ class Client {
}

/// Handles a decoded response from the server.
void _handleResponse(response) {
void _handleResponse(Object? response) {
if (response is List) {
response.forEach(_handleSingleResponse);
} else {
Expand All @@ -196,8 +197,9 @@ class Client {

/// Handles a decoded response from the server after batches have been
/// resolved.
void _handleSingleResponse(response) {
if (!_isResponseValid(response)) return;
void _handleSingleResponse(Object? response_) {
if (!_isResponseValid(response_)) return;
final response = response_ as Map;
var id = response['id'];
id = (id is String) ? int.parse(id) : id;
var request = _pendingRequests.remove(id)!;
Expand All @@ -212,7 +214,7 @@ class Client {
}

/// Determines whether the server's response is valid per the spec.
bool _isResponseValid(response) {
bool _isResponseValid(Object? response) {
if (response is! Map) return false;
if (response['jsonrpc'] != '2.0') return false;
var id = response['id'];
Expand Down
6 changes: 4 additions & 2 deletions lib/src/exception.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ class RpcException implements Exception {
Map<String, dynamic> serialize(Object? request) {
dynamic modifiedData;
if (data is Map && !(data as Map).containsKey('request')) {
modifiedData = Map.from(data as Map);
modifiedData['request'] = request;
modifiedData = {
...data as Map,
'request': request,
};
} else if (data == null) {
modifiedData = {'request': request};
} else {
Expand Down
24 changes: 12 additions & 12 deletions lib/src/parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ class Parameter extends Parameters {
// The parent parameters, used to construct [_path].
final Parameters _parent;

/// The key used to access [this], used to construct [_path].
final dynamic _key;
/// The key used to access `this`, used to construct [_path].
final Object _key;

/// A human-readable representation of the path of getters used to get this.
///
Expand All @@ -130,20 +130,22 @@ class Parameter extends Parameters {
return _key is int ? (_key + 1).toString() : jsonEncode(_key);
}

String quoteKey(key) {
String quoteKey(String key) {
if (key.contains(RegExp(r'[^a-zA-Z0-9_-]'))) return jsonEncode(key);
return key;
}

String computePath(params) {
String computePath(Parameter params) {
if (params._parent is! Parameter) {
return params._key is int ? '[${params._key}]' : quoteKey(params._key);
return params._key is int
? '[${params._key}]'
: quoteKey(params._key as String);
}

var path = computePath(params._parent);
return params._key is int
? '$path[${params._key}]'
: '$path.${quoteKey(params._key)}';
: '$path.${quoteKey(params._key as String)}';
}

return computePath(this);
Expand All @@ -152,8 +154,7 @@ class Parameter extends Parameters {
/// Whether this parameter exists.
bool get exists => true;

Parameter._(String method, value, this._parent, this._key)
: super(method, value);
Parameter._(super.method, super.value, this._parent, this._key);

/// Returns [value], or [defaultValue] if this parameter wasn't passed.
dynamic valueOr(Object? defaultValue) => value;
Expand Down Expand Up @@ -260,8 +261,7 @@ class Parameter extends Parameters {
/// If [value] doesn't exist, this returns [defaultValue].
Uri asUriOr(Uri defaultValue) => asUri;

/// Get a parameter named [named] that matches [test], or the value of calling
/// [orElse].
/// Get a parameter named [type] that matches [test].
///
/// [type] is used for the error message. It should begin with an indefinite
/// article.
Expand All @@ -271,7 +271,7 @@ class Parameter extends Parameters {
'"$method" must be $type, but was ${jsonEncode(value)}.');
}

dynamic _getParsed(String description, Function(String) parse) {
dynamic _getParsed(String description, void Function(String) parse) {
var string = asString;
try {
return parse(string);
Expand Down Expand Up @@ -316,7 +316,7 @@ class _MissingParameter extends Parameter {
@override
bool get exists => false;

_MissingParameter(String method, Parameters parent, key)
_MissingParameter(String method, Parameters parent, Object key)
: super._(method, null, parent, key);

@override
Expand Down
14 changes: 7 additions & 7 deletions lib/src/peer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ class Peer implements Client, Server {

/// A stream controller that forwards incoming messages to [_server] if
/// they're requests.
final _serverIncomingForwarder = StreamController(sync: true);
final _serverIncomingForwarder = StreamController<Object?>(sync: true);

/// A stream controller that forwards incoming messages to [_client] if
/// they're responses.
final _clientIncomingForwarder = StreamController(sync: true);
final _clientIncomingForwarder = StreamController<Object?>(sync: true);

@override
late final Future done = Future.wait([_client.done, _server.done]);
Expand Down Expand Up @@ -66,12 +66,12 @@ class Peer implements Client, Server {
onUnhandledError: onUnhandledError,
strictProtocolChecks: strictProtocolChecks);

/// Creates a [Peer] that communicates using decoded messages over [channel].
/// Creates a [Peer] that communicates using decoded messages over [_channel].
///
/// Unlike [Peer.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the peer won't begin listening to [channel] until
/// Note that the peer won't begin listening to [_channel] until
/// [Peer.listen] is called.
///
/// Unhandled exceptions in callbacks will be forwarded to [onUnhandledError].
Expand Down Expand Up @@ -102,7 +102,7 @@ class Peer implements Client, Server {
_client.sendNotification(method, parameters);

@override
void withBatch(Function() callback) => _client.withBatch(callback);
void withBatch(void Function() callback) => _client.withBatch(callback);

// Server methods.

Expand All @@ -111,7 +111,7 @@ class Peer implements Client, Server {
_server.registerMethod(name, callback);

@override
void registerFallback(Function(Parameters parameters) callback) =>
void registerFallback(void Function(Parameters parameters) callback) =>
_server.registerFallback(callback);

// Shared methods.
Expand Down Expand Up @@ -141,7 +141,7 @@ class Peer implements Client, Server {
// server since it knows how to send error responses.
_serverIncomingForwarder.add(message);
}
}, onError: (error, stackTrace) {
}, onError: (Object error, StackTrace stackTrace) {
_serverIncomingForwarder.addError(error, stackTrace);
}, onDone: close);
return done;
Expand Down
21 changes: 10 additions & 11 deletions lib/src/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ typedef ErrorCallback = void Function(dynamic error, dynamic stackTrace);
///
/// A server exposes methods that are called by requests, to which it provides
/// responses. Methods can be registered using [registerMethod] and
/// [registerFallback]. Requests can be handled using [handleRequest] and
/// [parseRequest].
/// [registerFallback].
///
/// Note that since requests can arrive asynchronously and methods can run
/// asynchronously, it's possible for multiple methods to be invoked at the same
Expand Down Expand Up @@ -72,7 +71,7 @@ class Server {

/// Creates a [Server] that communicates over [channel].
///
/// Note that the server won't begin listening to [requests] until
/// Note that the server won't begin listening to [channel] until
/// [Server.listen] is called.
///
/// Unhandled exceptions in callbacks will be forwarded to [onUnhandledError].
Expand All @@ -89,12 +88,12 @@ class Server {
strictProtocolChecks: strictProtocolChecks);

/// Creates a [Server] that communicates using decoded messages over
/// [channel].
/// [_channel].
///
/// Unlike [Server.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the server won't begin listening to [requests] until
/// Note that the server won't begin listening to [_channel] until
/// [Server.listen] is called.
///
/// Unhandled exceptions in callbacks will be forwarded to [onUnhandledError].
Expand All @@ -113,7 +112,8 @@ class Server {
///
/// [listen] may only be called once.
Future listen() {
_channel.stream.listen(_handleRequest, onError: (error, stackTrace) {
_channel.stream.listen(_handleRequest,
onError: (Object error, StackTrace stackTrace) {
_done.completeError(error, stackTrace);
_channel.sink.close();
}, onDone: () {
Expand Down Expand Up @@ -160,7 +160,7 @@ class Server {
/// completes to a JSON-serializable object. Any errors in [callback] will be
/// reported to the client as JSON-RPC 2.0 errors. [callback] may send custom
/// errors by throwing an [RpcException].
void registerFallback(Function(Parameters parameters) callback) {
void registerFallback(void Function(Parameters parameters) callback) {
_fallbacks.add(callback);
}

Expand All @@ -169,9 +169,8 @@ class Server {
/// [request] is expected to be a JSON-serializable object representing a
/// request sent by a client. This calls the appropriate method or methods for
/// handling that request and returns a JSON-serializable response, or `null`
/// if no response should be sent. [callback] may send custom
/// errors by throwing an [RpcException].
Future _handleRequest(request) async {
/// if no response should be sent.
Future _handleRequest(Object? request) async {
dynamic response;
if (request is List) {
if (request.isEmpty) {
Expand Down Expand Up @@ -241,7 +240,7 @@ class Server {
}

/// Validates that [request] matches the JSON-RPC spec.
void _validateRequest(request) {
void _validateRequest(Object? request) {
if (request is! Map) {
throw RpcException(
error_code.INVALID_REQUEST,
Expand Down
Loading

0 comments on commit 616937f

Please sign in to comment.