refactor(web-spawn): change api to be more like a shim of std::thread (#69)

* refactor(web-spawn): change api to be more like a shim of std::thread

* clippy
This commit is contained in:
sinu.eth
2025-08-19 08:09:53 -07:00
committed by GitHub
parent 5ffc674544
commit dea3db250c
5 changed files with 47 additions and 31 deletions

View File

@@ -1,6 +1,3 @@
[build]
target = "wasm32-unknown-unknown"
[target.'cfg(target_arch = "wasm32")']
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]

View File

@@ -1,6 +1,6 @@
[package]
name = "web-spawn"
version = "0.2.1"
version = "0.3.0"
edition = "2024"
description = "`std` spawn replacement for WASM in the browser."
repository = "https://github.com/tlsnotary/tlsn-utils"
@@ -10,11 +10,11 @@ license = "MIT OR Apache-2.0"
default = []
no-bundler = []
[target.'cfg(target_arch = "wasm32")'.dependencies]
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies]
futures = { version = "0.3" }
wasm-bindgen = { version = "0.2" }
wasm-bindgen-futures = { version = "0.4" }
crossbeam-channel = { version = "0.5" }
futures = { version = "0.3" }
js-sys = { version = "0.3" }
web-sys = { version = "0.3", features = [
"WorkerOptions",
@@ -23,5 +23,9 @@ web-sys = { version = "0.3", features = [
"Url",
] }
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.'dev-dependencies']
wasm-bindgen-test = { version = "0.3" }
[dev-dependencies]
pollster = { version = "0.4", features = ["macro"] }
futures = { version = "0.3" }

View File

@@ -14,17 +14,18 @@ Most notably, spawning is explicitly delegated to run in a background task and m
Add `web-spawn` as a dependency in your `Cargo.toml`:
```toml
[target.'cfg(target_arch = "wasm32")'.dependencies]
web-spawn = { version = "0.2" }
web-spawn = { version = "0.3" }
```
Then **you must ensure that spawning is initialized**. One way to do this is to re-export the following function:
Then **you must ensure that spawning is initialized**. One way to do this is to start the spawner from within your WASM module:
```rust,ignore
pub use web_spawn::start_spawner;
use wasm_bindgen_futures::JsFuture;
JsFuture::from(web_spawn::start_spawner()).await.unwrap();
```
On the javascript side this can be awaited:
Alternatively, this can be done on the javascript side:
```javascript
import init, { startSpawner } from /* your package */;
@@ -35,11 +36,10 @@ await init();
await startSpawner();
```
Now, in the rest of your Rust code you can conditionally use `web-spawn` anywhere you would otherwise use `std::thread::spawn`:
Now, in the rest of your Rust code you can use `web_spawn::spawn` anywhere you would otherwise use `std::thread::spawn`:
```rust,ignore
#[cfg(target_arch = "wasm32")]
use web_spawn as thread;
#[cfg(not(target_arch = "wasm32"))]
use std::thread;
```rust
use web_spawn::spawn;
assert_eq!(spawn(|| 1 + 1).join().unwrap(), 2);
```

View File

@@ -1,7 +1,10 @@
#![doc = include_str!("../README.md")]
#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
mod wasm;
#[cfg(target_arch = "wasm32")]
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
pub use wasm::*;
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
pub use std::thread::{Builder, JoinHandle, spawn};

View File

@@ -1,24 +1,29 @@
#![cfg(target_arch = "wasm32")]
use std::sync::atomic::AtomicBool;
use futures::channel::oneshot;
use web_spawn::spawn;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen_test::*;
use web_spawn::{spawn, start_spawner};
static INIT: AtomicBool = AtomicBool::new(false);
async fn init() {
// If it is set return immediately.
if INIT.swap(true, std::sync::atomic::Ordering::SeqCst) {
return;
if !INIT.swap(true, std::sync::atomic::Ordering::SeqCst) {
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
JsFuture::from(web_spawn::start_spawner()).await.unwrap();
}
JsFuture::from(start_spawner()).await.unwrap();
}
#[wasm_bindgen_test]
#[cfg_attr(
not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))),
pollster::test
)]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test::wasm_bindgen_test
)]
async fn test_pass() {
init().await;
@@ -29,7 +34,14 @@ async fn test_pass() {
assert_eq!(value, 42);
}
#[wasm_bindgen_test]
#[cfg_attr(
not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))),
pollster::test
)]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test::wasm_bindgen_test
)]
async fn test_join() {
init().await;