Skip to content

Commit 9898e62

Browse files
committed
Made requests work from within a web worker context
This looks pretty hacky until something is done regarding rustwasm/wasm-bindgen#1046
1 parent b76b048 commit 9898e62

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ features = [
143143
"RequestMode",
144144
"Response",
145145
"Window",
146+
"WorkerGlobalScope",
146147
]
147148

148149
[[example]]

src/wasm/client.rs

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,41 @@ impl Default for Client {
107107
}
108108
}
109109

110+
use wasm_bindgen::{prelude::*, JsCast};
111+
112+
thread_local! {
113+
static GLOBAL_WEB_CONTEXT: WebContext = WebContext::new();
114+
}
115+
116+
#[derive(Debug)]
117+
enum WebContext {
118+
Window(web_sys::Window),
119+
Worker(web_sys::WorkerGlobalScope),
120+
}
121+
122+
impl WebContext {
123+
fn new() -> Self {
124+
#[wasm_bindgen]
125+
extern "C" {
126+
type Global;
127+
128+
#[wasm_bindgen(method, getter, js_name = Window)]
129+
fn window(this: &Global) -> JsValue;
130+
131+
#[wasm_bindgen(method, getter, js_name = WorkerGlobalScope)]
132+
fn worker(this: &Global) -> JsValue;
133+
}
134+
135+
let global: Global = js_sys::global().unchecked_into();
136+
137+
if !global.window().is_undefined() {
138+
Self::Window(global.unchecked_into())
139+
} else if !global.worker().is_undefined() {
140+
Self::Worker(global.unchecked_into())
141+
} else {
142+
panic!("Only supported in a browser or web worker");
143+
}
144+
110145
async fn fetch(req: Request) -> crate::Result<Response> {
111146
// Build the js Request
112147
let mut init = web_sys::RequestInit::new();
@@ -143,9 +178,13 @@ async fn fetch(req: Request) -> crate::Result<Response> {
143178
.map_err(crate::error::builder)?;
144179

145180
// Await the fetch() promise
146-
let p = web_sys::window()
147-
.expect("window should exist")
148-
.fetch_with_request(&js_req);
181+
let p = GLOBAL_WEB_CONTEXT.with(|g| {
182+
match g {
183+
WebContext::Window(w) => w.fetch_with_request(&js_req),
184+
WebContext::Worker(w) => w.fetch_with_request(&js_req),
185+
}
186+
});
187+
149188
let js_resp = super::promise::<web_sys::Response>(p)
150189
.await
151190
.map_err(crate::error::request)?;
@@ -188,9 +227,3 @@ impl ClientBuilder {
188227
Ok(Client(()))
189228
}
190229
}
191-
192-
impl Default for ClientBuilder {
193-
fn default() -> Self {
194-
Self::new()
195-
}
196-
}

0 commit comments

Comments
 (0)