Skip to content

Commit

Permalink
Use direct global binding for fetch in place of web_sys fetch bindi…
Browse files Browse the repository at this point in the history
…ngs (#474)

This avoids the need to detect whether the module is running in the main
browser thread or in a WebWorker.

This matches how `setInterval` and related functions are handled by the
gloo-timers crate.

See rustwasm/wasm-bindgen#3863
  • Loading branch information
jbms authored Jul 18, 2024
1 parent dc0e61e commit 7efcfe4
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 31 deletions.
31 changes: 21 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions crates/net/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ http = [
'web-sys/Response',
'web-sys/ResponseInit',
'web-sys/ResponseType',
'web-sys/Window',
'web-sys/RequestCache',
'web-sys/RequestCredentials',
'web-sys/ObserverCallback',
Expand All @@ -88,7 +87,6 @@ http = [
'web-sys/ReadableStream',
'web-sys/Blob',
'web-sys/FormData',
'web-sys/WorkerGlobalScope',
]
# Enables the EventSource API
eventsource = [
Expand Down
33 changes: 14 additions & 19 deletions crates/net/src/http/request.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::http::{Headers, QueryParams, Response};
use crate::{js_to_error, Error};
use http::Method;
use js_sys::{ArrayBuffer, Reflect, Uint8Array};
use js_sys::{ArrayBuffer, Uint8Array};
use std::convert::{From, TryFrom, TryInto};
use std::fmt;
use std::str::FromStr;
use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
use wasm_bindgen_futures::JsFuture;
use web_sys::{
AbortSignal, FormData, ObserverCallback, ReadableStream, ReferrerPolicy, RequestCache,
Expand All @@ -16,6 +16,17 @@ use web_sys::{
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
use serde::de::DeserializeOwned;

#[wasm_bindgen]
extern "C" {
// Create a separate binding for `fetch` as a global, rather than using the
// existing Window/WorkerGlobalScope bindings defined by web_sys, for
// greater efficiency.
//
// https://github.com/rustwasm/wasm-bindgen/discussions/3863
#[wasm_bindgen(js_name = "fetch")]
fn fetch_with_request(request: &web_sys::Request) -> js_sys::Promise;
}

/// A wrapper round `web_sys::Request`: an http request to be used with the `fetch` API.
pub struct RequestBuilder {
options: web_sys::RequestInit,
Expand Down Expand Up @@ -320,23 +331,7 @@ impl Request {
/// Executes the request.
pub async fn send(self) -> Result<Response, Error> {
let request = self.0;
let global = js_sys::global();
let maybe_window =
Reflect::get(&global, &JsValue::from_str("Window")).map_err(js_to_error)?;
let promise = if !maybe_window.is_undefined() {
let window = global.dyn_into::<web_sys::Window>().unwrap();
window.fetch_with_request(&request)
} else {
let maybe_worker = Reflect::get(&global, &JsValue::from_str("WorkerGlobalScope"))
.map_err(js_to_error)?;
if !maybe_worker.is_undefined() {
let worker = global.dyn_into::<web_sys::WorkerGlobalScope>().unwrap();
worker.fetch_with_request(&request)
} else {
panic!("Unsupported JavaScript global context");
}
};

let promise = fetch_with_request(&request);
let response = JsFuture::from(promise).await.map_err(js_to_error)?;
response
.dyn_into::<web_sys::Response>()
Expand Down

0 comments on commit 7efcfe4

Please sign in to comment.