-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The getter 'onMessage' isn't defined for the type 'MessagePort'. #261
Comments
Try this for now import 'dart:async';
import 'dart:js_interop';
import 'package:web/web.dart';
class MessagePortStreamChannel {
MessagePortStreamChannel({required this.port}) {
_onReceiveMessageSubscription = port.onMessage.listen((message) {
_in.add(message.data as String);
});
_onPostMessageSubscription = _out.stream.listen(port.postMessage);
}
final MessagePort port;
final _in = StreamController<String>(sync: true);
final _out = StreamController<JSAny?>(sync: true);
late final StreamSubscription<MessageEvent> _onReceiveMessageSubscription;
late final StreamSubscription<JSAny?> _onPostMessageSubscription;
Future<void> dispose() async {
await _onReceiveMessageSubscription.cancel();
await _onPostMessageSubscription.cancel();
await _in.close();
await _out.close();
}
}
extension on MessagePort {
Stream<MessageEvent> get onMessage =>
EventStreamProviders.messageEvent.forTarget(this);
} |
We can add helpers here! |
With your example, i don't understand now how to call the class class MessageChannelArchethicDappClient extends AWCJsonRPCClient
implements ArchethicDAppClient {
MessageChannelArchethicDappClient({
required super.origin,
}) : super(
channelBuilder: () async {
if (awcAvailable != true) throw Failure.connectivity;
return MessagePortStreamChannel(
port: await asyncAWC,
);
},
disposeChannel: (StreamChannel<String> channel) async {
await (channel as MessagePortStreamChannel).dispose();
},
);
static bool get isAvailable => kIsWeb && awcAvailable == true;
}
For info, awc is @JS()
library awc;
import 'dart:async';
import 'dart:developer';
import 'dart:js_interop';
import 'package:web/web.dart';
external MessagePort? get awc;
external bool? get awcAvailable;
@JS('onAWCReady')
external set onAWCReady(void Function(MessagePort awc) f);
Future<MessagePort> get asyncAWC async {
if (awc != null) return awc!;
log('Wait for awc');
final awcReadyCompleter = Completer<MessagePort>();
if (awc != null) awcReadyCompleter.complete(awc!);
onAWCReady = (awc) {
log('AWC ready !');
};
return awcReadyCompleter.future;
} |
You might have to translate the StreamChannel from |
Finally, it works with import 'dart:async';
import 'dart:js_interop';
import 'package:archethic_wallet_client/archethic_wallet_client.dart';
import 'package:archethic_wallet_client/src/transport/common/awc_json_rpc_client.dart';
import 'package:archethic_wallet_client/src/transport/message_channel/message_channel.js.dart';
import 'package:flutter/foundation.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:web/web.dart';
class MessageChannelArchethicDappClient extends AWCJsonRPCClient
implements ArchethicDAppClient {
MessageChannelArchethicDappClient({
required super.origin,
}) : super(
channelBuilder: () async {
if (awcAvailable != true) throw Failure.connectivity;
return MessagePortStreamChannel(
port: await asyncAWC,
);
},
disposeChannel: (StreamChannel<String> channel) async {
await (channel as MessagePortStreamChannel).dispose();
},
);
static bool get isAvailable => kIsWeb && awcAvailable == true;
}
class MessagePortStreamChannel
with StreamChannelMixin<String>
implements StreamChannel<String> {
MessagePortStreamChannel({required this.port}) {
_onReceiveMessageSubscription = port.onMessage.listen((message) {
_in.add(message.data! as String);
});
_onPostMessageSubscription = _out.stream.listen((event) {
port.postMessage(event as JSAny?);
});
}
final MessagePort port;
final _in = StreamController<String>(sync: true);
final _out = StreamController<String>(sync: true);
late final StreamSubscription<MessageEvent> _onReceiveMessageSubscription;
late final StreamSubscription<String> _onPostMessageSubscription;
Future<void> dispose() async {
await _onReceiveMessageSubscription.cancel();
await _onPostMessageSubscription.cancel();
await _in.close();
await _out.close();
}
@override
StreamSink<String> get sink => _out.sink;
@override
Stream<String> get stream => _in.stream;
}
extension on MessagePort {
Stream<MessageEvent> get onMessage =>
EventStreamProviders.messageEvent.forTarget(this);
} |
hello @kevmoo I couldn't generate Chrome extension with my code in flutter 3.22
@JS()
library awc;
import 'dart:async';
import 'dart:developer';
import 'dart:js_interop';
import 'package:web/web.dart';
@JS()
external MessagePort? get awc;
@JS()
external bool? get awcAvailable;
@JS('onAWCReady')
external set onAWCReady(void Function(MessagePort awc) f);
Future<MessagePort> get asyncAWC async {
if (awc != null) {
return awc!;
}
log('Wait for awc');
final awcReadyCompleter = Completer<MessagePort>();
onAWCReady = (port) {
awcReadyCompleter.complete(port);
log('AWC ready !');
};
// Handle potential timeout or error (optional)
await Future.delayed(const Duration(seconds: 5), () {
if (!awcReadyCompleter.isCompleted) {
awcReadyCompleter.completeError(Exception('Timeout waiting for awc'));
}
});
return awcReadyCompleter.future;
}
Other errors with other part of my code: // ignore_for_file: avoid_setters_without_getters
@JS()
library awc;
import 'dart:async';
import 'package:js/js.dart';
@JS('archethic')
external ArchethicJS? get archethic;
@JS()
class ArchethicJS {
@JS('streamChannel')
external AWCStreamChannelJS? get streamChannel;
}
@JS()
class AWCStreamChannelJS {
@JS('state')
external AWCStreamChannelState get state;
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('connect')
external Object connect();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('close')
external Object close();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('send')
external Object send(String data);
@JS('onReceive')
external set onReceive(Future<void> Function(String data) callback);
@JS('onReady')
external set onReady(Future<void> Function() callback);
@JS('onClose')
external set onClose(Future<void> Function(String reason) callback);
}
enum AWCStreamChannelState {
connecting,
open,
closing,
closed,
}
to my new code with js_interop // ignore_for_file: avoid_setters_without_getters
@JS()
library awc;
import 'dart:js_interop';
extension type ArchethicJS._(JSObject _) implements JSObject {
@JS('streamChannel')
external AWCStreamChannelJS? get streamChannel;
}
@JS('archethic')
external ArchethicJS? get archethic;
extension type AWCStreamChannelJS._(JSObject _) implements JSObject {
@JS('state')
external AWCStreamChannelState get state;
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('connect')
external JSObject connect();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('close')
external JSObject close();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('send')
external JSObject send(JSString data);
@JS('onReceive')
external set onReceive(void Function(JSString data) callback);
@JS('onReady')
external set onReady(void Function() callback);
@JS('onClose')
external set onClose(void Function(JSString reason) callback);
}
enum AWCStreamChannelState {
connecting,
open,
closing,
closed,
}
i have these error too.
|
@srujzs ? |
to be confirmed but to help community with js_interop, i share a solution i think // ignore_for_file: avoid_setters_without_getters
@JS()
library awc;
import 'dart:js_interop';
extension type ArchethicJS._(JSObject _) implements JSObject {
@JS('streamChannel')
external AWCStreamChannelJS? get streamChannel;
}
@JS('archethic')
external ArchethicJS? get archethic;
extension type AWCStreamChannelJS._(JSObject _) implements JSObject {
@JS('state')
external AWCStreamChannelState get state;
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('connect')
external JSObject connect();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('close')
external JSObject close();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
@JS('send')
external JSObject send(JSString data);
@JS('onReceive')
external set onReceive(JSFunction callback);
@JS('onReady')
external set onReady(JSFunction callback);
@JS('onClose')
external set onClose(JSFunction callback);
}
@JS()
extension type AWCStreamChannelState._(JSObject _) implements JSObject {
external static AWCStreamChannelState get connecting;
external static AWCStreamChannelState get open;
external static AWCStreamChannelState get closing;
external static AWCStreamChannelState get closed;
}
|
FYI: you don't need to use |
Thx for the advice |
A few drive-by comments:
|
Thank you for advices. // ignore_for_file: avoid_setters_without_getters
@JS()
library awc;
import 'dart:js_interop';
extension type ArchethicJS._(JSObject _) implements JSObject {
@JS('streamChannel')
external AWCStreamChannelJS? get streamChannel;
}
@JS('archethic')
external ArchethicJS? get archethic;
extension type AWCStreamChannelJS._(JSObject _) implements JSObject {
external AWCStreamChannelState get state;
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
external JSPromise connect();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
external JSPromise close();
/// This returns a promise.
/// You must use `promiseTofuture` to call this from Dart code.
external JSPromise send(JSString data);
external set onReceive(JSFunction callback);
external set onReady(JSFunction callback);
external set onClose(JSFunction callback);
}
@JS()
extension type AWCStreamChannelState._(JSObject _) implements JSObject {
external static AWCStreamChannelState get connecting;
external static AWCStreamChannelState get open;
external static AWCStreamChannelState get closing;
external static AWCStreamChannelState get closed;
} but i met execution error on import 'dart:async';
import 'dart:developer';
import 'dart:js_interop';
import 'package:archethic_wallet_client/archethic_wallet_client.dart';
import 'package:archethic_wallet_client/src/transport/common/awc_json_rpc_client.dart';
import 'package:archethic_wallet_client/src/transport/webbrowser_extension/webbrowser_extension.js.dart';
import 'package:stream_channel/stream_channel.dart';
class WebBrowserExtensionDappClient extends AWCJsonRPCClient
implements ArchethicDAppClient {
WebBrowserExtensionDappClient({
required super.origin,
}) : super(
channelBuilder: () async {
if (archethic?.streamChannel == null) {
throw Failure.connectivity;
}
final streamChannel = WebBrowserExtensionStreamChannel(
streamChannel: archethic!.streamChannel!,
);
await streamChannel.connect();
return streamChannel;
},
disposeChannel: (channel) async {
await (channel as WebBrowserExtensionStreamChannel).dispose();
},
);
static bool get isAvailable => archethic?.streamChannel != null;
}
class WebBrowserExtensionStreamChannel
with StreamChannelMixin<String>
implements StreamChannel<String> {
WebBrowserExtensionStreamChannel({required this.streamChannel}) {
streamChannel.onReceive = (message) async {
log('[WBE] command received $message');
_in.add(message.toString());
log('[WBE] command received Done');
}.toJS;
_onPostMessageSubscription = _out.stream.listen((event) {
log('[WBE] send command $event');
streamChannel.send(event as JSString);
log('[WBE] send command Done');
});
streamChannel.onClose = (reason) async {
await dispose();
}.toJS;
}
Future<void> connect() async => streamChannel.connect();
final AWCStreamChannelJS streamChannel;
final _in = StreamController<String>(sync: true);
final _out = StreamController<String>(sync: true);
late final StreamSubscription<String> _onPostMessageSubscription;
Future<void> dispose() async {
await _onPostMessageSubscription.cancel();
await _in.close();
await _out.close();
}
@override
StreamSink<String> get sink => _out.sink;
@override
Stream<String> get stream => _in.stream;
} |
I'm guessing you're running with dart2wasm. Avoid casting If you're using |
Hello
I have a class
When i use
import 'package:web/web.dart';
,onMessage
method isn't defined for the type 'MessagePort'. but in the class we haveexternal EventHandler get onmessage;
i don't understand something to migrate my class to web package.
thx
The text was updated successfully, but these errors were encountered: