diff --git a/Cargo.lock b/Cargo.lock
index 4c4ce148..4f874968 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1062,6 +1062,20 @@ dependencies = [
"simd-adler32",
]
+[[package]]
+name = "fetch"
+version = "0.1.0"
+dependencies = [
+ "console_error_panic_hook",
+ "console_log",
+ "gloo-net",
+ "log",
+ "serde",
+ "wasm-bindgen",
+ "web-sys",
+ "xilem_web",
+]
+
[[package]]
name = "flate2"
version = "1.0.30"
@@ -1291,6 +1305,36 @@ dependencies = [
"xml-rs",
]
+[[package]]
+name = "gloo-net"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173"
+dependencies = [
+ "gloo-utils",
+ "http",
+ "js-sys",
+ "serde",
+ "serde_json",
+ "thiserror",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "gloo-utils"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa"
+dependencies = [
+ "js-sys",
+ "serde",
+ "serde_json",
+ "wasm-bindgen",
+ "web-sys",
+]
+
[[package]]
name = "glow"
version = "0.13.1"
@@ -1423,6 +1467,17 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
+[[package]]
+name = "http"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
[[package]]
name = "icu_collections"
version = "1.5.0"
@@ -4069,6 +4124,7 @@ version = "0.1.0"
dependencies = [
"peniko",
"wasm-bindgen",
+ "wasm-bindgen-futures",
"web-sys",
"xilem_core",
]
diff --git a/Cargo.toml b/Cargo.toml
index 81322d9a..35b33f43 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,7 @@ members = [
"xilem_web/web_examples/counter",
"xilem_web/web_examples/counter_custom_element",
"xilem_web/web_examples/elm",
+ "xilem_web/web_examples/fetch",
"xilem_web/web_examples/todomvc",
"xilem_web/web_examples/mathml_svg",
"xilem_web/web_examples/svgtoy",
diff --git a/xilem_web/Cargo.toml b/xilem_web/Cargo.toml
index 075a2933..00db6482 100644
--- a/xilem_web/Cargo.toml
+++ b/xilem_web/Cargo.toml
@@ -23,6 +23,7 @@ workspace = true
xilem_core = { workspace = true, features = ["kurbo"] }
peniko.workspace = true
wasm-bindgen = "0.2.92"
+wasm-bindgen-futures = "0.4.42"
[dependencies.web-sys]
version = "0.3.69"
diff --git a/xilem_web/src/attribute_value.rs b/xilem_web/src/attribute_value.rs
index bb649531..04124cb8 100644
--- a/xilem_web/src/attribute_value.rs
+++ b/xilem_web/src/attribute_value.rs
@@ -9,8 +9,11 @@ type CowStr = std::borrow::Cow<'static, str>;
#[derive(PartialEq, Clone, Debug, PartialOrd)]
pub enum AttributeValue {
True, // for the boolean true, this serializes to an empty string (e.g. for )
+ I16(i16),
+ U16(u16),
I32(i32),
U32(u32),
+ Usize(usize),
F32(f32),
F64(f64),
String(CowStr),
@@ -20,8 +23,11 @@ impl AttributeValue {
pub fn serialize(&self) -> CowStr {
match self {
AttributeValue::True => "".into(), // empty string is equivalent to a true set attribute
+ AttributeValue::I16(n) => n.to_string().into(),
+ AttributeValue::U16(n) => n.to_string().into(),
AttributeValue::I32(n) => n.to_string().into(),
AttributeValue::U32(n) => n.to_string().into(),
+ AttributeValue::Usize(n) => n.to_string().into(),
AttributeValue::F32(n) => n.to_string().into(),
AttributeValue::F64(n) => n.to_string().into(),
AttributeValue::String(s) => s.clone(),
@@ -56,9 +62,15 @@ impl IntoAttributeValue for AttributeValue {
}
}
-impl IntoAttributeValue for u32 {
+impl IntoAttributeValue for i16 {
fn into_attr_value(self) -> Option {
- Some(AttributeValue::U32(self))
+ Some(AttributeValue::I16(self))
+ }
+}
+
+impl IntoAttributeValue for u16 {
+ fn into_attr_value(self) -> Option {
+ Some(AttributeValue::U16(self))
}
}
@@ -68,6 +80,18 @@ impl IntoAttributeValue for i32 {
}
}
+impl IntoAttributeValue for u32 {
+ fn into_attr_value(self) -> Option {
+ Some(AttributeValue::U32(self))
+ }
+}
+
+impl IntoAttributeValue for usize {
+ fn into_attr_value(self) -> Option {
+ Some(AttributeValue::Usize(self))
+ }
+}
+
impl IntoAttributeValue for f32 {
fn into_attr_value(self) -> Option {
Some(AttributeValue::F32(self))
diff --git a/xilem_web/src/concurrent/memoized_await.rs b/xilem_web/src/concurrent/memoized_await.rs
new file mode 100644
index 00000000..55153919
--- /dev/null
+++ b/xilem_web/src/concurrent/memoized_await.rs
@@ -0,0 +1,255 @@
+// Copyright 2024 the Xilem Authors and the Druid Authors
+// SPDX-License-Identifier: Apache-2.0
+
+use std::{future::Future, marker::PhantomData};
+
+use wasm_bindgen::{closure::Closure, JsCast, UnwrapThrowExt};
+use wasm_bindgen_futures::spawn_local;
+use xilem_core::{MessageResult, Mut, NoElement, View, ViewId, ViewPathTracker};
+
+use crate::{DynMessage, OptionalAction, ViewCtx};
+
+/// Await a future returned by `init_future` invoked with the argument `data`, `callback` is called with the output of the future. `init_future` will be invoked again, when `data` changes. Use [`memoized_await`] for construction of this [`View`]
+pub struct MemoizedAwait {
+ init_future: InitFuture,
+ data: Data,
+ callback: Callback,
+ debounce_ms: usize,
+ reset_debounce_on_update: bool,
+ #[allow(clippy::type_complexity)]
+ phantom: PhantomData (State, Action, OA, F, FOut)>,
+}
+
+impl
+ MemoizedAwait
+where
+ FOut: std::fmt::Debug + 'static,
+ F: Future