Skip to content

Commit

Permalink
Made requests work from within a web worker context
Browse files Browse the repository at this point in the history
This looks pretty hacky until something is done regarding rustwasm/wasm-bindgen#1046
  • Loading branch information
Globidev committed Mar 17, 2020
1 parent f6ff7f4 commit 801e2ba
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ features = [
"RequestMode",
"Response",
"Window",
"WorkerGlobalScope",
]

[[example]]
Expand Down
48 changes: 44 additions & 4 deletions src/wasm/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,43 @@ impl Client {
}
}

use wasm_bindgen::{prelude::*, JsCast};

thread_local! {
static GLOBAL_WEB_CONTEXT: WebContext = WebContext::new();
}

#[derive(Debug)]
enum WebContext {
Window(web_sys::Window),
Worker(web_sys::WorkerGlobalScope),
}

impl WebContext {
fn new() -> Self {
#[wasm_bindgen]
extern "C" {
type Global;

#[wasm_bindgen(method, getter, js_name = Window)]
fn window(this: &Global) -> JsValue;

#[wasm_bindgen(method, getter, js_name = WorkerGlobalScope)]
fn worker(this: &Global) -> JsValue;
}

let global: Global = js_sys::global().unchecked_into();

if !global.window().is_undefined() {
Self::Window(global.unchecked_into())
} else if !global.worker().is_undefined() {
Self::Worker(global.unchecked_into())
} else {
panic!("Only supported in a browser or web worker");
}
}
}

async fn fetch(req: Request) -> crate::Result<Response> {
// Build the js Request
let mut init = web_sys::RequestInit::new();
Expand Down Expand Up @@ -136,10 +173,13 @@ async fn fetch(req: Request) -> crate::Result<Response> {
.map_err(crate::error::wasm)
.map_err(crate::error::builder)?;

// Await the fetch() promise
let p = web_sys::window()
.expect("window should exist")
.fetch_with_request(&js_req);
let p = GLOBAL_WEB_CONTEXT.with(|g| {
match g {
WebContext::Window(w) => w.fetch_with_request(&js_req),
WebContext::Worker(w) => w.fetch_with_request(&js_req),
}
});

let js_resp = super::promise::<web_sys::Response>(p)
.await
.map_err(crate::error::request)?;
Expand Down

0 comments on commit 801e2ba

Please sign in to comment.