* Change the suspense streaming context after suspense is resolved in the router * Wait for the suspense context before streaming the first chunk in ssr * forward more response parts * warn * extract the hydration format into a crate * Fix hydration when no data is sent * forward web and server features * Fix suspense that starts on the client * fix use_server_future on the client * Add documentation for fullstack hooks and protocol * downgrade rust edition * fix clippy * fix tests * fix clippy * Fix pure web compile * undo changes to the fullstack router example * fix formatting
118 lines
2.8 KiB
Rust
118 lines
2.8 KiB
Rust
// This test is used by playwright configured in the root of the repo
|
|
// Tests:
|
|
// - Streaming hydration
|
|
// - Suspense
|
|
// - Server futures
|
|
|
|
#![allow(non_snake_case, unused)]
|
|
use dioxus::prelude::*;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
fn app() -> Element {
|
|
// Start streaming immediately
|
|
use_hook(commit_initial_chunk);
|
|
let mut count = use_signal(|| 0);
|
|
|
|
rsx! {
|
|
button {
|
|
id: "increment-carousel-button",
|
|
onclick: move |_| count += 1,
|
|
"Increment"
|
|
}
|
|
button {
|
|
id: "decrement-carousel-button",
|
|
onclick: move |_| count -= 1,
|
|
"Decrement"
|
|
}
|
|
div {
|
|
"Hello world"
|
|
}
|
|
div {
|
|
for i in count()..count() + 3 {
|
|
SuspenseBoundary {
|
|
key: "{i}",
|
|
fallback: |_| rsx! {
|
|
"Loading..."
|
|
},
|
|
SuspendedComponent {
|
|
id: i
|
|
}
|
|
}
|
|
}
|
|
}
|
|
div { "footer 123" }
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq)]
|
|
enum ResolvedOn {
|
|
Server,
|
|
Client,
|
|
}
|
|
|
|
impl ResolvedOn {
|
|
#[cfg(feature = "web")]
|
|
const CURRENT: Self = Self::Client;
|
|
#[cfg(not(feature = "web"))]
|
|
const CURRENT: Self = Self::Server;
|
|
}
|
|
|
|
#[component]
|
|
fn SuspendedComponent(id: i32) -> Element {
|
|
let resolved_on = use_server_future(move || async move {
|
|
async_std::task::sleep(std::time::Duration::from_secs(1)).await;
|
|
ResolvedOn::CURRENT
|
|
})?()
|
|
.unwrap();
|
|
|
|
let mut count = use_signal(|| 0);
|
|
|
|
rsx! {
|
|
div {
|
|
id: "outer-{id}",
|
|
"outer suspense result: {resolved_on:?}"
|
|
button {
|
|
id: "outer-button-{id}",
|
|
onclick: move |_| count += 1,
|
|
"{count}"
|
|
}
|
|
SuspenseBoundary {
|
|
fallback: |_| rsx! {
|
|
"Loading... more"
|
|
},
|
|
NestedSuspendedComponent {
|
|
id
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[component]
|
|
fn NestedSuspendedComponent(id: i32) -> Element {
|
|
let resolved_on = use_server_future(move || async move {
|
|
async_std::task::sleep(std::time::Duration::from_secs(1)).await;
|
|
ResolvedOn::CURRENT
|
|
})?()
|
|
.unwrap();
|
|
let mut count = use_signal(|| 0);
|
|
rsx! {
|
|
div {
|
|
"nested suspense result: {resolved_on:?}"
|
|
button {
|
|
id: "nested-button-{id}",
|
|
onclick: move |_| count += 1,
|
|
"{count}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
LaunchBuilder::new()
|
|
.with_cfg(server_only! {
|
|
dioxus::fullstack::ServeConfig::builder().enable_out_of_order_streaming()
|
|
})
|
|
.launch(app);
|
|
}
|