commit 72616938aa47b3f61603a2e228c85adb3d1d0e0e
parent 453c7a9ff4a4501b6a49d201d931898d9eb17894
Author: triesap <tyson@radroots.org>
Date: Mon, 2 Feb 2026 16:46:26 +0000
app: fix wasm build helpers
- handle response array_buffer and cache cloning
- update number format and random values usage
- fix file picker closure sender lifetime
- normalize navigator locale option handling
Diffstat:
6 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/crates/app-lib/src/file.rs b/crates/app-lib/src/file.rs
@@ -112,14 +112,18 @@ pub async fn select_file() -> Result<Option<web_sys::File>, FileError> {
input.set_accept("*/*");
let (sender, receiver) = futures::channel::oneshot::channel();
+ let sender = Rc::new(RefCell::new(Some(sender)));
let closure_holder: Rc<RefCell<Option<wasm_bindgen::closure::Closure<dyn FnMut(_)>>>> =
Rc::new(RefCell::new(None));
let closure_ref = closure_holder.clone();
+ let sender_ref = Rc::clone(&sender);
let input_clone = input.clone();
*closure_holder.borrow_mut() = Some(wasm_bindgen::closure::Closure::wrap(Box::new(
move |_event: web_sys::Event| {
let file = input_clone.files().and_then(|list| list.get(0));
- let _ = sender.send(file);
+ if let Some(sender) = sender_ref.borrow_mut().take() {
+ let _ = sender.send(file);
+ }
closure_ref.borrow_mut().take();
},
) as Box<dyn FnMut(_)>));
diff --git a/crates/app-lib/src/locale.rs b/crates/app-lib/src/locale.rs
@@ -29,7 +29,7 @@ pub fn resolve_locale(locales: &[&str], navigator_locale: Option<&str>) -> Strin
pub fn get_locale(locales: &[&str]) -> String {
#[cfg(target_arch = "wasm32")]
{
- let navigator_locale = web_sys::window().map(|window| window.navigator().language());
+ let navigator_locale = web_sys::window().and_then(|window| window.navigator().language());
resolve_locale(locales, navigator_locale.as_deref())
}
#[cfg(not(target_arch = "wasm32"))]
diff --git a/crates/utils/src/async/mod.rs b/crates/utils/src/async/mod.rs
@@ -2,6 +2,7 @@
use crate::error::RadrootsAppUtilsError;
use std::future::Future;
+#[cfg(not(target_arch = "wasm32"))]
use std::time::Duration;
pub async fn exe_iter<F, Fut>(
diff --git a/crates/utils/src/cache/mod.rs b/crates/utils/src/cache/mod.rs
@@ -51,7 +51,10 @@ pub async fn asset_cache_fetch_bytes(
if !response.ok() {
return Ok(None);
}
- let buffer = wasm_bindgen_futures::JsFuture::from(response.array_buffer())
+ let promise = response
+ .array_buffer()
+ .map_err(|_| RadrootsAppUtilsError::Unavailable)?;
+ let buffer = wasm_bindgen_futures::JsFuture::from(promise)
.await
.map_err(|_| RadrootsAppUtilsError::Unavailable)?;
let array = js_sys::Uint8Array::new(&buffer);
@@ -84,8 +87,6 @@ async fn asset_cache_fetch_impl(
url: &str,
config: Option<&AssetCacheFetchConfig>,
) -> Result<AssetResponse, RadrootsAppUtilsError> {
- use wasm_bindgen::JsCast;
-
let cache_name = cache_name_resolve(config);
let cache_key = cache_key_resolve(url);
if let Some(cached) = cache_read(&cache_name, &cache_key).await? {
@@ -93,7 +94,10 @@ async fn asset_cache_fetch_impl(
}
let response = fetch_with_init(url, config).await?;
if response.ok() || response.type_() == web_sys::ResponseType::Opaque {
- cache_write(&cache_name, &cache_key, response.clone()).await?;
+ let response = response
+ .clone()
+ .map_err(|_| RadrootsAppUtilsError::Unavailable)?;
+ cache_write(&cache_name, &cache_key, response).await?;
}
Ok(response)
}
@@ -114,10 +118,10 @@ async fn fetch_with_init(
use wasm_bindgen::JsCast;
let window = web_sys::window().ok_or(RadrootsAppUtilsError::Unavailable)?;
- let mut init = web_sys::RequestInit::new();
+ let init = web_sys::RequestInit::new();
if let Some(request_init) = config.and_then(|config| config.request_init.as_ref()) {
if let Some(cache_mode) = request_init.cache {
- init.cache(cache_mode.to_request_cache());
+ init.set_cache(cache_mode.to_request_cache());
}
}
let response = wasm_bindgen_futures::JsFuture::from(window.fetch_with_str_and_init(url, &init))
diff --git a/crates/utils/src/currency/mod.rs b/crates/utils/src/currency/mod.rs
@@ -88,7 +88,12 @@ fn fmt_price_value(locale: &str, value: f64, currency: FiatCurrency) -> String {
&JsValue::from_f64(2.0),
);
let formatter = js_sys::Intl::NumberFormat::new(&locales, &options);
- formatter.format(value).into()
+ let formatted = formatter
+ .format()
+ .call1(&JsValue::NULL, &JsValue::from_f64(value))
+ .ok()
+ .and_then(|value| value.as_string());
+ formatted.unwrap_or_else(|| format!("{} {:.2}", currency.as_upper(), value))
}
#[cfg(not(target_arch = "wasm32"))]
diff --git a/crates/utils/src/numbers/mod.rs b/crates/utils/src/numbers/mod.rs
@@ -44,12 +44,10 @@ fn random_u64() -> Result<u64, RadrootsAppUtilsError> {
let crypto = window
.crypto()
.map_err(|_| RadrootsAppUtilsError::Unavailable)?;
- let array = js_sys::Uint8Array::new_with_length(8);
+ let mut bytes = [0u8; 8];
crypto
- .get_random_values_with_u8_array(&array)
+ .get_random_values_with_u8_array(&mut bytes)
.map_err(|_| RadrootsAppUtilsError::Unavailable)?;
- let mut bytes = [0u8; 8];
- array.copy_to(&mut bytes);
Ok(u64::from_le_bytes(bytes))
}