Merge branch 'master'

This commit is contained in:
Tsavo Knott 2025-03-30 16:20:21 -04:00
commit 6dc48c5f70
18 changed files with 68 additions and 56 deletions

View File

@ -7,6 +7,7 @@
* Upgrade to `package:lints` version 5.0.0 and Dart SDK version 3.5.0.
* Upgrade `example/grpc-web` code.
* Update xhr transport to migrate off legacy JS/HTML apis.
* Use `package:web` to get `HttpStatus`
## 4.0.1

View File

@ -25,7 +25,7 @@ it should raise analysis issues as you edit; alternatively validate from the
Terminal:
```
dartanalyzer lib test
dart analyze
```
All analysis warnings and errors must be fixed; hints should be considered.
@ -33,8 +33,7 @@ All analysis warnings and errors must be fixed; hints should be considered.
## Running tests
```
pub get
pub run test
dart test
```
gRPC-web tests require [`envoy`](
@ -69,4 +68,4 @@ early on.
so.
## Updating protobuf definitions
Sometimes we might need to update the generated dart files from the protos included in `lib/src/protos`. To do this, run the script `tool/regenerate.sh` from the project root and it will update the generated dart files in `lib/src/geneerated`.
Sometimes we might need to update the generated dart files from the protos included in `lib/src/protos`. To do this, run the script `tool/regenerate.sh` from the project root and it will update the generated dart files in `lib/src/generated`.

View File

@ -1,9 +1,8 @@
The [Dart](https://www.dart.dev/) implementation of
[gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.
[![Dart](https://github.com/grpc/grpc-dart/actions/workflows/dart.yml/badge.svg)](https://github.com/grpc/grpc-dart/actions/workflows/dart.yml)
[![pub package](https://img.shields.io/pub/v/grpc.svg)](https://pub.dev/packages/grpc)
The [Dart](https://www.dart.dev/) implementation of
[gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first.
## Learn more

View File

@ -1,23 +1,22 @@
# https://dart.dev/guides/language/analysis-options
include: package:lints/recommended.yaml
analyzer:
errors:
# These should be fixed or ignored in the proto generator
# These should be fixed or ignored in the proto generator.
implementation_imports: ignore
no_leading_underscores_for_local_identifiers: ignore
unintended_html_in_doc_comment: ignore
linter:
rules:
#true
always_declare_return_types: true
cancel_subscriptions: true
close_sinks: true
directives_ordering: true
omit_local_variable_types: true
prefer_final_locals: true
prefer_single_quotes: true
test_types_in_equals: true
prefer_relative_imports: true
#false
unintended_html_in_doc_comment: false
- always_declare_return_types
- cancel_subscriptions
- close_sinks
- directives_ordering
- omit_local_variable_types
- prefer_final_locals
- prefer_relative_imports
- prefer_single_quotes
# Enable once 3.7 is stable.
# - strict_top_level_inference
- test_types_in_equals

View File

@ -14,8 +14,7 @@
// limitations under the License.
import 'dart:async';
import 'dart:html';
import 'package:web/web.dart';
import 'src/generated/echo.pbgrpc.dart';
class EchoApp {
@ -56,13 +55,23 @@ class EchoApp {
}
void _addMessage(String message, String cssClass) {
final classes = cssClass.split(' ');
querySelector('#first')!.after(DivElement()
..classes.add('row')
..append(Element.tag('h2')
..append(SpanElement()
..classes.add('label')
..classes.addAll(classes)
document.querySelector('#first')!.after(HTMLDivElement()
..classList.add('row')
..append(HTMLHeadingElement.h2()
..append(HTMLSpanElement()
..classList.add('label')
..classList.addAll(cssClass)
..text = message)));
}
}
// The documentation of DOMTokenList.add implies it can handle multiple classes,
// but in Chrome at least it does not.
extension AddAll on DOMTokenList {
void addAll(String cssClass) {
final classes = cssClass.split(' ');
for (final c in classes) {
add(c);
}
}
}

View File

@ -9,6 +9,7 @@ dependencies:
grpc:
path: ../../
protobuf: ^3.0.0
web: ^1.1.0
dev_dependencies:
build_runner: ^2.4.13

View File

@ -12,21 +12,20 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:html';
import 'package:grpc/grpc_web.dart';
import 'package:grpc_web/app.dart';
import 'package:grpc_web/src/generated/echo.pbgrpc.dart';
import 'package:web/web.dart';
void main() {
final channel = GrpcWebClientChannel.xhr(Uri.parse('http://localhost:8080'));
final service = EchoServiceClient(channel);
final app = EchoApp(service);
final button = querySelector('#send') as ButtonElement;
final button = document.querySelector('#send') as HTMLButtonElement;
button.onClick.listen((e) async {
final msg = querySelector('#msg') as TextInputElement;
final value = msg.value!.trim();
final msg = document.querySelector('#msg') as HTMLInputElement;
final value = msg.value.trim();
msg.value = '';
if (value.isEmpty) return;

View File

@ -13,8 +13,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// ignore: dangling_library_doc_comments
/// Status detail types and error codes
export 'package:grpc/src/generated/google/rpc/error_details.pb.dart';
export 'src/auth/auth.dart' show BaseAuthenticator;

View File

@ -203,7 +203,7 @@ class ClientCall<Q, R> implements Response {
}
}
void onConnectionError(error) {
void onConnectionError(Object error) {
_terminateWithError(GrpcError.unavailable('Error connecting: $error'));
}
@ -398,7 +398,7 @@ class ClientCall<Q, R> implements Response {
/// Handler for response errors. Forward the error to the [_responses] stream,
/// wrapped if necessary.
void _onResponseError(error, StackTrace stackTrace) {
void _onResponseError(Object error, StackTrace stackTrace) {
if (error is GrpcError) {
_responseError(error, stackTrace);
return;
@ -436,7 +436,7 @@ class ClientCall<Q, R> implements Response {
/// Error handler for the requests stream. Something went wrong while trying
/// to send the request to the server. Abort the request, and forward the
/// error to the user code on the [_responses] stream.
void _onRequestError(error, StackTrace stackTrace) {
void _onRequestError(Object error, StackTrace stackTrace) {
if (error is! GrpcError) {
error = GrpcError.unknown(error.toString());
}

View File

@ -271,7 +271,7 @@ class Http2ClientConnection implements connection.ClientConnection {
return _pendingCalls.isNotEmpty;
}
void _handleConnectionFailure(error) {
void _handleConnectionFailure(Object error) {
_disconnect();
if (_state == ConnectionState.shutdown || _state == ConnectionState.idle) {
return;

View File

@ -309,7 +309,7 @@ class ServerHandler extends ServiceCall {
// -- Active state, outgoing response data --
void _onResponse(response) {
void _onResponse(dynamic response) {
try {
final bytes = _descriptor.serialize(response);
if (!_headersSent) {
@ -333,7 +333,7 @@ class ServerHandler extends ServiceCall {
sendTrailers();
}
void _onResponseError(error, trace) {
void _onResponseError(Object error, StackTrace trace) {
if (error is GrpcError) {
_sendError(error, trace);
} else {
@ -413,7 +413,7 @@ class ServerHandler extends ServiceCall {
// -- All states, incoming error / stream closed --
void _onError(error) {
void _onError(Object error) {
// Exception from the incoming stream. Most likely a cancel request from the
// client, so we treat it as such.
_timeoutTimer?.cancel();

View File

@ -13,4 +13,4 @@
// See the License for the specific language governing permissions and
// limitations under the License.
export 'io_bits_io.dart' if (dart.library.html) 'io_bits_web.dart';
export 'io_bits_io.dart' if (dart.library.js_interop) 'io_bits_web.dart';

View File

@ -13,7 +13,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
export 'dart:html' show HttpStatus;
export 'package:web/web.dart' show HttpStatus;
/// Unavailable on the web
class InternetAddress {}

View File

@ -4,6 +4,11 @@ version: 4.0.2
repository: https://github.com/open-runtime/grpc-dart
topics:
- grpc
- protocols
- rpc
environment:
sdk: ^3.5.0
@ -32,10 +37,5 @@ dev_dependencies:
fake_async: ^1.3.1
false_secrets:
- interop/server1.key
- test/data/localhost.key
topics:
- grpc
- rpc
- protocols
- interop/server1.key
- test/data/localhost.key

View File

@ -12,6 +12,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
@TestOn('browser')
library;

View File

@ -81,8 +81,14 @@ static_resources:
expose_headers: custom-header-1,grpc-status,grpc-message
http_filters:
- name: envoy.filters.http.grpc_web
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: echo_service
connect_timeout: 0.25s

View File

@ -77,7 +77,7 @@ class ClientData {
{required this.address, required this.port, required this.sendPort});
}
void client(clientData) async {
void client(ClientData clientData) async {
final channel = grpc.ClientChannel(
clientData.address,
port: clientData.port,
@ -107,7 +107,7 @@ Future<void> main() async {
]);
await server.serve(address: address, port: 0);
final receivePort = ReceivePort();
Isolate.spawn(
Isolate.spawn<ClientData>(
client,
ClientData(
address: address,

View File

@ -137,7 +137,7 @@ void checkFinishEvent(List<Map> events) {
expect(e.length, 2);
}
void main([args = const <String>[]]) {
void main(List<String> args) {
test('Test gRPC timeline logging', () async {
final vmService = await testee();
final timeline = await vmService.getVMTimeline();