core: wasm groundwork — target-split deps + gate native-only transports
First real step toward the web/WASM target. The dependency graph is now target-conditional: the legacy transports' OS-socket deps (tokio net, mdns-sd, webrtc) + UniFFI + native reqwest live under cfg(not(wasm32)); wasm32 gets a minimal tokio (sync/macros), the reqwest fetch backend, wasm-bindgen-futures, and iroh with default-features off. The SSE/RTC/LAN transport modules are gated to native (they need OS sockets). getrandom's wasm rng is wired (build-cfg for 0.4 + the js-feature alias trick for the transitive 0.2). Effect: `cargo build --target wasm32-unknown-unknown --features iroh-transport` goes from "deps won't compile at all" to 15 well-understood errors, isolated to four structural items: UniFFI (decouple the FFI layer for wasm), iroh's wasm feature set (presets/gossip-net), the tokio runtime (→ spawn_local + ?Send), and reqwest .timeout(). Native builds (default + iroh + examples) are byte-unaffected — all verified clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Generated
+2
@@ -4852,6 +4852,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"chacha20poly1305",
|
"chacha20poly1305",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"getrandom 0.2.17",
|
||||||
"getrandom 0.4.3",
|
"getrandom 0.4.3",
|
||||||
"iroh",
|
"iroh",
|
||||||
"iroh-blobs",
|
"iroh-blobs",
|
||||||
@@ -4863,6 +4864,7 @@ dependencies = [
|
|||||||
"sha2 0.11.0",
|
"sha2 0.11.0",
|
||||||
"tokio",
|
"tokio",
|
||||||
"uniffi",
|
"uniffi",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
"webrtc",
|
"webrtc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
+31
-12
@@ -15,31 +15,50 @@ name = "tethercore"
|
|||||||
name = "uniffi-bindgen"
|
name = "uniffi-bindgen"
|
||||||
path = "src/bin/uniffi-bindgen.rs"
|
path = "src/bin/uniffi-bindgen.rs"
|
||||||
|
|
||||||
|
# Common, wasm-safe dependencies (no OS sockets / threads).
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uniffi = { version = "0.28", features = ["cli"] }
|
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream", "json"] }
|
|
||||||
tokio = { version = "1", features = ["rt-multi-thread", "time", "sync", "macros", "net", "io-util"] }
|
|
||||||
futures-util = "0.3"
|
futures-util = "0.3"
|
||||||
webrtc = "0.17.1"
|
|
||||||
mdns-sd = "0.20.0"
|
|
||||||
sha2 = "0.11.0"
|
sha2 = "0.11.0"
|
||||||
bytes = "1.12.0"
|
bytes = "1.12.0"
|
||||||
chacha20poly1305 = "0.10.1"
|
chacha20poly1305 = "0.10.1"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
getrandom = "0.4.3"
|
|
||||||
# M4: the iroh Mesh, behind the `iroh-transport` feature (off by default, so the
|
|
||||||
# UniFFI/xcframework/agent builds are untouched). When on, IrohTransport replaces
|
|
||||||
# the hand-rolled SSE/RTC/LAN stack.
|
|
||||||
iroh = { version = "1", optional = true }
|
|
||||||
iroh-gossip = { version = "0.101", optional = true }
|
|
||||||
iroh-blobs = { version = "0.103", optional = true }
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
iroh-transport = ["dep:iroh", "dep:iroh-gossip", "dep:iroh-blobs"]
|
iroh-transport = ["dep:iroh", "dep:iroh-gossip", "dep:iroh-blobs"]
|
||||||
|
|
||||||
|
# ── Native (desktop/mobile): legacy transports + UniFFI + full tokio ──
|
||||||
|
# The hand-rolled SSE/RTC/LAN stack and its OS-socket deps live here; none of it
|
||||||
|
# compiles to wasm. iroh (behind the feature) takes full default features.
|
||||||
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
|
uniffi = { version = "0.28", features = ["cli"] }
|
||||||
|
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "stream", "json"] }
|
||||||
|
tokio = { version = "1", features = ["rt-multi-thread", "time", "sync", "macros", "net", "io-util"] }
|
||||||
|
webrtc = "0.17.1"
|
||||||
|
mdns-sd = "0.20.0"
|
||||||
|
getrandom = "0.4.3"
|
||||||
|
iroh = { version = "1", optional = true }
|
||||||
|
iroh-gossip = { version = "0.101", optional = true }
|
||||||
|
iroh-blobs = { version = "0.103", optional = true }
|
||||||
|
|
||||||
|
# ── wasm32 (browser): iroh-only, no OS sockets / UniFFI ──
|
||||||
|
# Browser iroh is relay-only; reqwest uses fetch; the runtime is the JS event
|
||||||
|
# loop (wasm-bindgen-futures) instead of a tokio runtime.
|
||||||
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
tokio = { version = "1", features = ["sync", "macros"] }
|
||||||
|
reqwest = { version = "0.12", default-features = false, features = ["json"] }
|
||||||
|
# wasm rng: getrandom 0.4 uses a build-cfg (--cfg getrandom_backend="wasm_js"),
|
||||||
|
# but a transitive getrandom 0.2 needs the `js` *feature* — enable it via the
|
||||||
|
# rename-alias trick (cargo unifies it with the transitive copy).
|
||||||
|
getrandom = "0.4.3"
|
||||||
|
getrandom_02 = { package = "getrandom", version = "0.2", features = ["js"] }
|
||||||
|
wasm-bindgen-futures = "0.4"
|
||||||
|
iroh = { version = "1", optional = true, default-features = false }
|
||||||
|
iroh-gossip = { version = "0.101", optional = true, default-features = false }
|
||||||
|
iroh-blobs = { version = "0.103", optional = true, default-features = false }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# Iroh spikes (examples/iroh_*.rs) link iroh directly regardless of the feature.
|
# Iroh spikes (examples/iroh_*.rs) link iroh directly regardless of the feature.
|
||||||
iroh = "1"
|
iroh = "1"
|
||||||
|
|||||||
@@ -32,7 +32,10 @@ use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
|
|||||||
mod crypto;
|
mod crypto;
|
||||||
#[cfg(feature = "iroh-transport")]
|
#[cfg(feature = "iroh-transport")]
|
||||||
mod iroh;
|
mod iroh;
|
||||||
|
// Legacy transports use OS sockets (tokio net / mdns / webrtc) — native only.
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod lan;
|
mod lan;
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod rtc;
|
mod rtc;
|
||||||
|
|
||||||
use crypto::Crypto;
|
use crypto::Crypto;
|
||||||
@@ -698,14 +701,17 @@ impl Dedup {
|
|||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// SSE transport — the reliable floor: server relay over text/event-stream.
|
// SSE transport — the reliable floor: server relay over text/event-stream.
|
||||||
|
// Native only (reqwest streaming / bytes_stream isn't on the wasm fetch backend).
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
struct SseTransport {
|
struct SseTransport {
|
||||||
cfg: Config,
|
cfg: Config,
|
||||||
http: reqwest::Client,
|
http: reqwest::Client,
|
||||||
events: EventTx,
|
events: EventTx,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
impl Transport for SseTransport {
|
impl Transport for SseTransport {
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
"sse"
|
"sse"
|
||||||
@@ -757,6 +763,7 @@ impl Transport for SseTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
impl SseTransport {
|
impl SseTransport {
|
||||||
async fn stream_once(&self, running: &AtomicBool) -> Result<(), String> {
|
async fn stream_once(&self, running: &AtomicBool) -> Result<(), String> {
|
||||||
let url = format!(
|
let url = format!(
|
||||||
@@ -816,6 +823,7 @@ impl SseTransport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
async fn post(http: &reqwest::Client, cfg: &Config, msg: &Message) -> Result<(), String> {
|
async fn post(http: &reqwest::Client, cfg: &Config, msg: &Message) -> Result<(), String> {
|
||||||
let url = format!("{}/api/send", cfg.server.trim_end_matches('/'));
|
let url = format!("{}/api/send", cfg.server.trim_end_matches('/'));
|
||||||
let kind = if msg.kind.is_empty() { "clipboard" } else { msg.kind.as_str() };
|
let kind = if msg.kind.is_empty() { "clipboard" } else { msg.kind.as_str() };
|
||||||
|
|||||||
Reference in New Issue
Block a user