Open princefarming opened 4 months ago
Thanks for filing! It's a little difficult to discern where the issue originates from. I can see some proposed fixes in different locations, but I can't quite tell from the issue what the original code looks like. Is there a repro you can perhaps share? Is the interop code in Flutter?
To add to @srujzs questions: where is the definition of JsMap
that the gitlab issue discuses?
If something started failing due to a browser version update, it's soemtimes possible that the issue lies in how dart2js associates interceptors and something changing that breaks what interceptor is associated with the map-iterator. This typically affects package:js
because it can't intercept anything that has a corresponding native type, but it wouldn't affect APIs written with @staticInterop
or dart:js_interop
, which are more resilient to changes in the underlying JavaScript types.
That said, testing Chrome 120, 121, and 122 I don't see any observable differences there at first glance. For example (new Map()).entries()
seems to show "Map Iterator" as the result of Object.prototype.toString.call
on all 3 browsers, which is what dart2js would use for determining the interceptor.
@srujzs @sigmundch thanks for the reply!
i've prepared a minimum code project here: https://github.com/kayatmin/jsinterop
this is only reproducible when flutter run --release
or flutter run --profile
, works perfectly with debug mode.
chrome console is generating this error msg NoSuchMethodError: method not found: 'mv'
:
here's the flutter doctor -v
:
[√] Flutter (Channel stable, 3.16.5, on Microsoft Windows [Version
10.0.22631.3235], locale en-CA)
• Flutter version 3.16.5 on channel stable at $\versions\3.16.5
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 78666c8dc5 (3 months ago), 2023-12-19 16:14:14 -0800
• Engine revision 3f3e560236
• Dart version 3.2.3
• DevTools version 2.28.4
[√] Windows Version (Installed version of Windows is version 10 or higher)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.1) • Android SDK at $\Android\Sdk • Platform android-33-ext4, build-tools 33.0.1 • ANDROID_HOME = $\Android\Sdk • Java binary at: $\Android\Android Studio\jbr\bin\java • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-9505619) • All Android licenses accepted.
[√] Chrome - develop for the web • Chrome at $\Google\Chrome\Application\chrome.exe
[√] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.5.4) • Visual Studio at $\2022\Community • Visual Studio Community 2022 version 17.5.33530.505 • Windows 10 SDK version 10.0.22000.0
[√] Android Studio (version 2022.1) • Android Studio at $\Android\Android Studio • Flutter plugin can be installed from: https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-9505619)
[√] VS Code (version 1.87.0) • VS Code at $\Programs\Microsoft VS Code • Flutter extension version 3.84.0
[√] VS Code (version 1.88.0-insider) • VS Code at $\Programs\Microsoft VS Code Insiders • Flutter extension version 3.85.20240301
[√] Connected device (3 available) • Windows (desktop) • windows • windows-x64 • Microsoft Windows [Version 10.0.22631.3235] • Chrome (web) • chrome • web-javascript • Google Chrome 122.0.6261.95 • Edge (web) • edge • web-javascript • Microsoft Edge 122.0.2365.59
[√] Network resources • All expected network resources are available.
• No issues found!
It looks like for some reason we aren't intercepting the resulting Map Iterator
as LegacyJavaScriptObject
. dart2js believes that the interceptor is JavaScriptObject
instead. The former has the right method:
next$0(receiver) {
return receiver.next();
},
whereas calling next
on the latter results in calling this:
next$0($receiver) {
return this.noSuchMethod$1($receiver, A.createInvocationMirror("next", "next$0", 0, [], [], 0));
},
Normally this occurs when a type is bound to an @Native
class but I can't see any such classes binding Map Iterator
.
Because that's the case, you may be able to use @staticInterop
instead to work around this. Replace the IteratorJS
definition with the following:
@JS()
@staticInterop
class IteratorJS<T> {
external factory IteratorJS();
}
extension IteratorJSExtension<T> on IteratorJS<T> {
external IteratorValue<T> next();
}
This makes flutter run --profile
work for me.
It looks like Chrome 122 made Map Iterator
a subtype of Iterator
and that's the cause for the change in interceptor: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator. It looks like Firefox has not made this change and so the issue isn't reproducible there. Since we intercept Iterator
as DomIterator
in dart:html
that would explain this. package:js
types that aren't written with @staticInterop
can't interop with types that are reserved by dart:html
, and therefore we come across the above issue.
The recommendation is to try to move to static interop, which avoids the limitations of package:js
types when it comes to not being able to interop with types that are reserved in dart:html
. The @staticInterop
code above should fix this issue for you, but long-term, consider migrating to interop extension types instead using dart:js_interop
: https://dart.dev/interop/js-interop.
We have come across a critical issue where our users are unable to join a video call, when using the latest update from Chrome (version 122, for macOS it was -> 122.0.6261.69). The version before this worked fine and there was no code change from our end.
This issue below in gitlab describes the issue that we and others were facing which seems to originate in the DART:JS package, we also posted the workaround to fix the issue: https://gitlab.com/twilio-flutter/programmable-video/-/issues/261
My apologies if this isn't the correct place to post this, at this point we aren't quite sure where the responsibility lies.