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")'] [target.'cfg(target_arch = "wasm32")']
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"] rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals"]

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "web-spawn" name = "web-spawn"
version = "0.2.1" version = "0.3.0"
edition = "2024" edition = "2024"
description = "`std` spawn replacement for WASM in the browser." description = "`std` spawn replacement for WASM in the browser."
repository = "https://github.com/tlsnotary/tlsn-utils" repository = "https://github.com/tlsnotary/tlsn-utils"
@@ -10,11 +10,11 @@ license = "MIT OR Apache-2.0"
default = [] default = []
no-bundler = [] 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 = { version = "0.2" }
wasm-bindgen-futures = { version = "0.4" } wasm-bindgen-futures = { version = "0.4" }
crossbeam-channel = { version = "0.5" } crossbeam-channel = { version = "0.5" }
futures = { version = "0.3" }
js-sys = { version = "0.3" } js-sys = { version = "0.3" }
web-sys = { version = "0.3", features = [ web-sys = { version = "0.3", features = [
"WorkerOptions", "WorkerOptions",
@@ -23,5 +23,9 @@ web-sys = { version = "0.3", features = [
"Url", "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" } 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`: Add `web-spawn` as a dependency in your `Cargo.toml`:
```toml ```toml
[target.'cfg(target_arch = "wasm32")'.dependencies] web-spawn = { version = "0.3" }
web-spawn = { version = "0.2" }
``` ```
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 ```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 ```javascript
import init, { startSpawner } from /* your package */; import init, { startSpawner } from /* your package */;
@@ -35,11 +36,10 @@ await init();
await startSpawner(); 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 ```rust
#[cfg(target_arch = "wasm32")] use web_spawn::spawn;
use web_spawn as thread;
#[cfg(not(target_arch = "wasm32"))] assert_eq!(spawn(|| 1 + 1).join().unwrap(), 2);
use std::thread;
``` ```

View File

@@ -1,7 +1,10 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#[cfg(target_arch = "wasm32")] #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
mod wasm; mod wasm;
#[cfg(target_arch = "wasm32")] #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
pub use wasm::*; 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 std::sync::atomic::AtomicBool;
use futures::channel::oneshot; 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_futures::JsFuture;
use wasm_bindgen_test::*;
use web_spawn::{spawn, start_spawner};
static INIT: AtomicBool = AtomicBool::new(false); static INIT: AtomicBool = AtomicBool::new(false);
async fn init() { async fn init() {
// If it is set return immediately. if !INIT.swap(true, std::sync::atomic::Ordering::SeqCst) {
if INIT.swap(true, std::sync::atomic::Ordering::SeqCst) { #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
return; 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() { async fn test_pass() {
init().await; init().await;
@@ -29,7 +34,14 @@ async fn test_pass() {
assert_eq!(value, 42); 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() { async fn test_join() {
init().await; init().await;