Skip to content

Commit

Permalink
feat(wasm-ext): Add web-sys WebTransport
Browse files Browse the repository at this point in the history
  • Loading branch information
oblique committed Jun 1, 2023
1 parent 224bede commit 928731b
Show file tree
Hide file tree
Showing 11 changed files with 870 additions and 15 deletions.
73 changes: 61 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions libp2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ full = [
"wasm-bindgen",
"wasm-ext",
"wasm-ext-websocket",
"wasm-ext-webtransport",
"webrtc",
"websocket",
"yamux",
Expand Down Expand Up @@ -81,6 +82,7 @@ uds = ["dep:libp2p-uds"]
wasm-bindgen = ["futures-timer/wasm-bindgen", "instant/wasm-bindgen", "getrandom/js", "libp2p-swarm/wasm-bindgen", "libp2p-gossipsub?/wasm-bindgen"]
wasm-ext = ["dep:libp2p-wasm-ext"]
wasm-ext-websocket = ["wasm-ext", "libp2p-wasm-ext?/websocket"]
wasm-ext-webtransport = ["wasm-ext", "libp2p-wasm-ext?/webtransport"]
webrtc = ["dep:libp2p-webrtc", "libp2p-webrtc?/pem"]
websocket = ["dep:libp2p-websocket"]
yamux = ["dep:libp2p-yamux"]
Expand Down
28 changes: 26 additions & 2 deletions transports/wasm-ext/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,41 @@ keywords = ["peer-to-peer", "libp2p", "networking"]
categories = ["network-programming", "asynchronous"]

[dependencies]
thiserror = { version = "1.0.4", optional = true }
futures = "0.3.28"
js-sys = "0.3.63"
web-sys = { version = "0.3.63", optional = true }
libp2p-core = { workspace = true }
parity-send-wrapper = "0.1.0"
libp2p-identity = { workspace = true, optional = true }
libp2p-noise = { workspace = true, optional = true }
send_wrapper = { version = "0.6.0", features = ["futures"] }
wasm-bindgen = "0.2.86"
wasm-bindgen-futures = "0.4.36"
log = "0.4.18"

[features]
websocket = []
webtransport = [
"thiserror",
"libp2p-identity",
"libp2p-noise",
"dep:web-sys",
"web-sys?/ReadableStreamDefaultReader",
"web-sys?/WritableStreamDefaultWriter",
"web-sys?/WebTransport",
"web-sys?/WebTransportHash",
"web-sys?/WebTransportOptions",
"web-sys?/WebTransportBidirectionalStream",
"web-sys?/WebTransportReceiveStream",
"web-sys?/WebTransportSendStream",
]

# Passing arguments to the docsrs builder in order to properly document cfg's.
[dev-dependencies]
multibase = "0.9.1"
wasm-bindgen-test = "0.3.36"
getrandom = { version = "0.2.9", features = ["js"] }

# Passing arguments to the docsrs builder in order to properly document cfg's.
# More information: https://docs.rs/about/builds#cross-compiling
[package.metadata.docs.rs]
all-features = true
Expand Down
8 changes: 7 additions & 1 deletion transports/wasm-ext/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,17 @@ use libp2p_core::{
transport::{ListenerId, TransportError, TransportEvent},
Multiaddr, Transport,
};
use parity_send_wrapper::SendWrapper;
use send_wrapper::SendWrapper;
use std::{collections::VecDeque, error, fmt, io, mem, pin::Pin, task::Context, task::Poll};
use wasm_bindgen::{prelude::*, JsCast};
use wasm_bindgen_futures::JsFuture;

#[cfg(feature = "webtransport")]
pub mod webtransport;

#[cfg(test)]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

/// Contains the definition that one must match on the JavaScript side.
pub mod ffi {
use wasm_bindgen::prelude::*;
Expand Down
11 changes: 11 additions & 0 deletions transports/wasm-ext/src/webtransport.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
mod cached_js_promise;
mod connection;
mod error;
mod stream;
mod transport;
mod utils;

pub use self::connection::Connection;
pub use self::error::Error;
pub use self::stream::Stream;
pub use self::transport::{Config, Transport};
48 changes: 48 additions & 0 deletions transports/wasm-ext/src/webtransport/cached_js_promise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use futures::FutureExt;
use js_sys::Promise;
use send_wrapper::SendWrapper;
use std::task::{ready, Context, Poll};
use wasm_bindgen::JsValue;
use wasm_bindgen_futures::JsFuture;

pub struct CachedJsPromise {
cached: Option<SendWrapper<JsFuture>>,
}

impl CachedJsPromise {
pub fn new() -> Self {
CachedJsPromise { cached: None }
}

pub fn maybe_init_and_poll<F>(
&mut self,
cx: &mut Context,
init: F,
) -> Poll<Result<JsValue, JsValue>>
where
F: FnOnce() -> Promise,
{
if self.cached.is_none() {
self.cached = Some(SendWrapper::new(JsFuture::from(init())));
}

self.poll(cx)
}

pub fn poll(&mut self, cx: &mut Context) -> Poll<Result<JsValue, JsValue>> {
let val = ready!(self
.cached
.as_mut()
.expect("CachedJsPromise not initialized")
.poll_unpin(cx));

// Future finished, drop it
self.cached.take();

Poll::Ready(val)
}

pub fn is_active(&self) -> bool {
self.cached.is_some()
}
}
Loading

0 comments on commit 928731b

Please sign in to comment.