Closed Schwusch closed 1 year ago
It makes sense that reloading main
doesn't work while reloading web_usb
does since void Function(JavaScriptObject) <: void Function(USBDevice)
. I think this is a result of erasing the types in both libraries and then when hot reloading, doing type-checking without erasing the reloaded library.
Perhaps the right thing here is to erase before type-checking, but that may have its own issues.
Late response to this but I've been working on a similar bug on modular compilation and erasure that I believe should fix this. The fix should be to do a global transform once the whole program is compiled (before code generation). This way, reloading modules should not result in inconsistencies. I'll respond back once that's landed.
Thanks a lot for the update. Are you referring to https://dart-review.googlesource.com/c/sdk/+/253000/ ?
Great work, I saw you landed a few others as well. I look forward to not working around the bug ☺️
Yup, it has landed: https://github.com/dart-lang/sdk/commit/61abaeda3f84e6d45c4a70689b08b798713bc5c1
A dev version should be available in the next few hours. Flutter rolls might take a little while (I believe they're on the cadence of several days, but I'm not sure). Please let me know if you still come across this issue then, thanks!
I pulled from Flutter master
release:
Flutter 3.1.0-0.0.pre.2032 • channel master • https://github.com/flutter/flutter.git
Framework • revision 195fa0b728 (2 hours ago) • 2022-08-02 05:39:06 -0400
Engine • revision 4b19256979
Tools • Dart 2.19.0 (build 2.19.0-53.0.dev) • DevTools 2.16.0
And the problem still persists. I take it the fix landed in 2.19.0-52.0.dev
per this commit: https://github.com/dart-lang/sdk/commit/cdad34a0392362c0e580048918cb6ea481e84662
Am I thinking correctly?
Thanks for trying this! I fear you're right after trying this locally as well. :(
We'll likely need to pipe this lower into DDC somewhere where we can do a global transform at the point where the different uses of DDC intersect (expression evaluation, this, etc.). I'll respond back once I have something.
This might not help you @srujzs, but I've worked around the problem by creating a wrapper/proxy class for the static interop code.
That fixes hot restart in the GUI code for me at least.
I now noticed the wrapper/proxy solution actually broke the functionality, since the callback is no longer called.
Maybe the closure passed to allowInterop
broke because of it?
Yeah, that should work since that's a Dart class and we're not doing any transformations there. It is a bit cumbersome though, which is unfortunate.
I think that breaks because the listener in the allowInterop
call is being passed a USBDevice
, instead of the wrapper class you created. You can probably work around this using:
typedef USBConnectionEventListener = void Function(UsbDeviceWrapper event);
extension PropsUsb on Usb {
void subscribeConnect(USBConnectionEventListener listener) {
callMethod(this, 'addEventListener', [
'connect',
allowInterop((USBConnectionEvent event) => listener(UsbDeviceWrapper(event.device)))
]);
}
}
Hi @Schwusch, I think this should be fixed with 2.19.0-351.0.dev looking at some modular tests. This should be in Flutter master by now if you'd like to give it a try.
Hi, I just checked with latest on master, and it seems to be working in all the use cases I have, thank you 🙏 I'd say this issue is resolved. Great work 💪
Awesome, thanks for trying it out!
When hot reloading I get this error:
This is when hot reloading any change in
main.dart
in this Flutter project: https://github.com/Schwusch/dart_js_bug_repro. It is the smallest reproducible code example I could make. When making a change and hot reloading inother.dart
, everything works as expected and the code is hot reloaded. I am using a M1 MacOSX 12.4 Monterey.Reproduced with both:
and:
main.dart
other.dart