diff --git a/flutter_package/example/native/hub/Cargo.toml b/flutter_package/example/native/hub/Cargo.toml
index c99cdbba..df1e29c5 100644
--- a/flutter_package/example/native/hub/Cargo.toml
+++ b/flutter_package/example/native/hub/Cargo.toml
@@ -15,13 +15,13 @@ crate-type = ["lib", "cdylib", "staticlib"]
rinf = "7.0.4"
prost = "0.13.0"
tokio = { version = "1", features = ["rt", "sync", "time", "macros"] }
-tokio_with_wasm = { version = "0.7.1", features = [
+tokio_with_wasm = { version = "0.7.2", features = [
"rt",
"sync",
"time",
"macros",
] }
-wasm-bindgen = "0.2.93"
+wasm-bindgen = "0.2.95"
messages = "0.3.1"
anyhow = "1.0.89"
sample_crate = { path = "../sample_crate" }
diff --git a/flutter_package/example/web/index.html b/flutter_package/example/web/index.html
index 1aa025dd..29b58086 100644
--- a/flutter_package/example/web/index.html
+++ b/flutter_package/example/web/index.html
@@ -21,7 +21,7 @@
-
+
diff --git a/flutter_package/lib/src/interface_web.dart b/flutter_package/lib/src/interface_web.dart
index cac787e0..07a2ab79 100644
--- a/flutter_package/lib/src/interface_web.dart
+++ b/flutter_package/lib/src/interface_web.dart
@@ -2,7 +2,6 @@
import 'load_web.dart';
import 'dart:typed_data';
-import 'dart:js' as js;
import 'interface.dart';
import 'dart:async';
import 'dart:convert';
@@ -16,11 +15,11 @@ void setCompiledLibPathReal(String path) {
Future prepareInterfaceReal(
AssignRustSignal assignRustSignal,
) async {
+ // Load the JavaScript module.
await loadJsFile();
- // Listen to Rust via JavaScript
- final jsObject = js.context['rinf'] as js.JsObject;
- jsObject['send_rust_signal_extern'] = (
+ // Listen to Rust via JavaScript.
+ rinfBindingsObject['send_rust_signal_extern'] = (
int messageId,
Uint8List messageBytes,
Uint8List binary,
@@ -39,8 +38,7 @@ void startRustLogicReal() {
if (wasAlreadyLoaded) {
return;
}
- final jsObject = js.context['rinf'] as js.JsObject;
- jsObject.callMethod('start_rust_logic_extern', []);
+ wasmBindingsObject.callMethod('start_rust_logic_extern', []);
}
void stopRustLogicReal() {
@@ -52,8 +50,7 @@ void sendDartSignalReal(
Uint8List messageBytes,
Uint8List binary,
) {
- final jsObject = js.context['rinf'] as js.JsObject;
- jsObject.callMethod('send_dart_signal_extern', [
+ wasmBindingsObject.callMethod('send_dart_signal_extern', [
messageId,
messageBytes,
binary,
diff --git a/flutter_package/lib/src/load_web.dart b/flutter_package/lib/src/load_web.dart
index 3b7fd41f..ba850643 100644
--- a/flutter_package/lib/src/load_web.dart
+++ b/flutter_package/lib/src/load_web.dart
@@ -6,22 +6,33 @@ import 'dart:async';
String? jsLibPath;
-// When Dart performs hot restart,
-// the `rinf` object is already defined
-// as a global JavaScript variable.
-final wasAlreadyLoaded = js.context.hasProperty('rinf');
-
void setJsLibPath(String path) {
jsLibPath = path;
}
+bool wasAlreadyLoaded = false;
+js.JsObject rinfBindingsObject = js.context['rinfBindings'];
+js.JsObject wasmBindingsObject = js.context['wasmBindings'];
+
Future loadJsFile() async {
+ // When Dart performs hot restart,
+ // the `rinfBindings` JavaScript object is already defined
+ // as a global JavaScript variable.
+ wasAlreadyLoaded = js.context.hasProperty('rinfBindings');
+
+ // Stop loading if it already has been done.
if (wasAlreadyLoaded) {
return;
}
+ // Create the namespace JavaScript object.
+ // This namespace object is used by Rust
+ // to call functions defined in Dart.
+ js.context['rinfBindings'] = js.JsObject.jsify({});
+
+ // Prepare to await the module load.
final loadCompleter = Completer();
- js.context['completeRinfLoad'] = loadCompleter.complete;
+ rinfBindingsObject['completeRinfLoad'] = loadCompleter.complete;
// Flutter app doesn't always have the top-level path of the domain.
// Sometimes, the flutter app might be placed in a lower path.
@@ -36,10 +47,10 @@ Future loadJsFile() async {
scriptElement.type = 'module';
scriptElement.innerHtml = '''
import init, * as wasmBindings from "$fullUrl";
+globalThis.wasmBindings = wasmBindings;
await init();
-window.rinf = { ...wasmBindings };
-completeRinfLoad();
-delete window.completeRinfLoad;
+rinfBindings.completeRinfLoad();
+delete rinfBindings.completeRinfLoad;
''';
document.head!.append(scriptElement);
diff --git a/flutter_package/template/native/hub/Cargo.toml b/flutter_package/template/native/hub/Cargo.toml
index 8d06899e..c3f8d114 100644
--- a/flutter_package/template/native/hub/Cargo.toml
+++ b/flutter_package/template/native/hub/Cargo.toml
@@ -17,5 +17,5 @@ prost = "0.13.0"
tokio = { version = "1", features = ["rt", "macros"] }
# Uncomment below to target the web.
-# tokio_with_wasm = { version = "0.7.1", features = ["rt", "macros"] }
-# wasm-bindgen = "0.2.93"
+# tokio_with_wasm = { version = "0.7.2", features = ["rt", "macros"] }
+# wasm-bindgen = "0.2.95"
diff --git a/rust_crate/Cargo.toml b/rust_crate/Cargo.toml
index c4df9b1f..b8a95e90 100644
--- a/rust_crate/Cargo.toml
+++ b/rust_crate/Cargo.toml
@@ -25,8 +25,8 @@ backtrace = { version = "0.3.69", optional = true }
[target.'cfg(target_family = "wasm")'.dependencies]
js-sys = "0.3.70"
-wasm-bindgen = "0.2.93"
-wasm-bindgen-futures = "0.4.43"
+wasm-bindgen = "0.2.95"
+wasm-bindgen-futures = "0.4.45"
[lints.clippy]
unwrap_used = "deny"
diff --git a/rust_crate/src/error.rs b/rust_crate/src/error.rs
index 14754371..f69030b8 100644
--- a/rust_crate/src/error.rs
+++ b/rust_crate/src/error.rs
@@ -6,6 +6,7 @@ pub enum RinfError {
NoDartIsolate,
CannotDecodeMessage,
NoSignalHandler,
+ NoBindings,
}
impl fmt::Display for RinfError {
@@ -20,6 +21,9 @@ impl fmt::Display for RinfError {
Self::NoSignalHandler => {
write!(f, "Could not find the handler for Dart signal")
}
+ Self::NoBindings => {
+ write!(f, "Rinf bindings are not ready")
+ }
}
}
}
diff --git a/rust_crate/src/interface_web.rs b/rust_crate/src/interface_web.rs
index 9e849056..173c3141 100644
--- a/rust_crate/src/interface_web.rs
+++ b/rust_crate/src/interface_web.rs
@@ -22,12 +22,18 @@ where
#[wasm_bindgen]
extern "C" {
- #[wasm_bindgen(js_namespace = rinf, catch)]
+ // The reason this extern function is marked `catch`
+ // and returns a `Result` is that the
+ // `rinfBindings` JavaScript object created by Dart
+ // does not exist in web workers; it is only available
+ // in the main JavaScript thread. Loading the function
+ // fails in web workers.
+ #[wasm_bindgen(js_namespace = rinfBindings, catch)]
pub fn send_rust_signal_extern(
resource: i32,
message_bytes: Uint8Array,
binary: Uint8Array,
- ) -> Result<(), JsValue>; // catch the JS exception
+ ) -> Result<(), JsValue>;
}
pub fn send_rust_signal_real(
@@ -35,15 +41,10 @@ pub fn send_rust_signal_real(
message_bytes: Vec,
binary: Vec,
) -> Result<(), RinfError> {
- match send_rust_signal_extern(
+ let result = send_rust_signal_extern(
message_id,
js_sys::Uint8Array::from(message_bytes.as_slice()),
js_sys::Uint8Array::from(binary.as_slice()),
- ) {
- Ok(_) => Ok(()),
- Err(e) => {
- crate::debug_print!("An error occured during the launch: {e:?}");
- Err(RinfError::NoSignalHandler)
- }
- }
+ );
+ result.map_err(|_| RinfError::NoBindings)
}