diff --git a/Cargo.toml b/Cargo.toml index 7ba80244ab6..3e31931a4b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,7 +78,7 @@ serde = ["libp2p-core/serde", "libp2p-kad?/serde", "libp2p-gossipsub?/serde"] tcp = ["dep:libp2p-tcp"] tokio = ["libp2p-swarm/tokio", "libp2p-mdns?/tokio", "libp2p-tcp?/tokio", "libp2p-dns?/tokio", "libp2p-quic?/tokio", "libp2p-webrtc?/tokio"] uds = ["dep:libp2p-uds"] -wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js"] +wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen"] wasm-ext = ["dep:libp2p-wasm-ext"] wasm-ext-websocket = ["wasm-ext", "libp2p-wasm-ext?/websocket"] webrtc = ["dep:libp2p-webrtc", "libp2p-webrtc?/pem"] diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 223a8f5651b..c17b00203a9 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -24,6 +24,8 @@ rand = "0.8" smallvec = "1.6.1" thiserror = "1.0" void = "1" +wasm-bindgen-futures = { version = "0.4.33", optional = true } +getrandom = { version = "0.2.3", features = ["js"], optional = true } # Explicit dependency to be used in `wasm-bindgen` feature [target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "unknown")))'.dependencies] async-std = { version = "1.6.2", optional = true } @@ -33,6 +35,7 @@ tokio = { version = "1.15", features = ["rt"], optional = true } macros = ["dep:libp2p-swarm-derive"] tokio = ["dep:tokio"] async-std = ["dep:async-std"] +wasm-bindgen = ["dep:wasm-bindgen-futures", "dep:getrandom"] [dev-dependencies] async-std = { version = "1.6.2", features = ["attributes"] } diff --git a/swarm/src/executor.rs b/swarm/src/executor.rs index dc17c174c48..ab7ab6b1fdf 100644 --- a/swarm/src/executor.rs +++ b/swarm/src/executor.rs @@ -59,3 +59,14 @@ impl Executor for AsyncStdExecutor { let _ = async_std::task::spawn(future); } } + +#[cfg(feature = "wasm-bindgen")] +#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct WasmBindgenExecutor; + +#[cfg(feature = "wasm-bindgen")] +impl Executor for WasmBindgenExecutor { + fn exec(&self, future: Pin + Send>>) { + wasm_bindgen_futures::spawn_local(future) + } +} diff --git a/swarm/src/lib.rs b/swarm/src/lib.rs index 6bf89b4c341..0c5cadcf021 100644 --- a/swarm/src/lib.rs +++ b/swarm/src/lib.rs @@ -420,6 +420,29 @@ where builder.build() } + /// Builds a new `Swarm` with a wasm executor. + /// Background tasks will be executed by the browser on the next micro-tick. + /// + /// Spawning a task is similar too: + /// ```typescript + /// function spawn(task: () => Promise) { + /// task() + /// } + /// ``` + #[cfg(feature = "wasm-bindgen")] + pub fn with_wasm_executor( + transport: transport::Boxed<(PeerId, StreamMuxerBox)>, + behaviour: TBehaviour, + local_peer_id: PeerId, + ) -> Self { + Self::with_executor( + transport, + behaviour, + local_peer_id, + crate::executor::WasmBindgenExecutor, + ) + } + /// Builds a new `Swarm` without an executor, instead using the current task. /// /// ## ⚠️ Performance warning