Skip to content

Commit 45b14f8

Browse files
committed
warn
1 parent d824325 commit 45b14f8

File tree

22 files changed

+297
-154
lines changed

22 files changed

+297
-154
lines changed

Cargo.lock

Lines changed: 26 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ members = [
3838
"packages/document",
3939
"packages/extension",
4040
"packages/fullstack",
41+
"packages/fullstack-hooks",
42+
"packages/fullstack-data",
4143
"packages/generational-box",
4244
"packages/history",
4345
"packages/hooks",
@@ -102,7 +104,7 @@ members = [
102104
"packages/playwright-tests/suspense-carousel",
103105
"packages/playwright-tests/nested-suspense",
104106
"packages/playwright-tests/cli-optimization",
105-
"packages/playwright-tests/wasm-split-harness", "packages/streaming-context",
107+
"packages/playwright-tests/wasm-split-harness"
106108
]
107109

108110
[workspace.package]
@@ -141,7 +143,8 @@ dioxus-cli-opt = { path = "packages/cli-opt", version = "0.6.2" }
141143
dioxus-devtools = { path = "packages/devtools", version = "0.6.2" }
142144
dioxus-devtools-types = { path = "packages/devtools-types", version = "0.6.2" }
143145
dioxus-fullstack = { path = "packages/fullstack", version = "0.6.2" }
144-
dioxus-streaming-context = { path = "packages/streaming-context", version = "0.6.3" }
146+
dioxus-fullstack-hooks = { path = "packages/fullstack-hooks", version = "0.6.3" }
147+
dioxus-fullstack-protocol = { path = "packages/fullstack-protocol", version = "0.6.3" }
145148
dioxus_server_macro = { path = "packages/server-macro", version = "0.6.2", default-features = false }
146149
dioxus-dx-wire-format = { path = "packages/dx-wire-format", version = "0.6.2" }
147150
dioxus-logger = { path = "packages/logger", version = "0.6.2" }

examples/fullstack-router/Cargo.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ publish = false
99
[dependencies]
1010
dioxus = { workspace = true, features = ["fullstack", "router"] }
1111
axum = { workspace = true, optional = true }
12-
tokio = {workspace = true, features = ["full"], optional = true }
12+
tokio = { workspace = true, features = ["full"], optional = true }
1313
serde = { version = "1.0.159", features = ["derive"] }
14+
reqwest = { workspace = true, features = ["json"] }
15+
http = { workspace = true, optional = true }
1416

1517
[features]
1618
default = []
17-
server = ["axum", "dioxus/server"]
19+
server = ["axum", "dioxus/server", "dep:tokio", "dep:http"]
1820
web = ["dioxus/web"]
1921

examples/fullstack-router/src/main.rs

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ use dioxus::prelude::*;
88

99
fn main() {
1010
dioxus::LaunchBuilder::new()
11-
.with_cfg(server_only!(ServeConfig::builder().incremental(
12-
IncrementalRendererConfig::default()
13-
.invalidate_after(std::time::Duration::from_secs(120)),
14-
)))
11+
.with_cfg(server_only!(
12+
ServeConfig::builder().enable_out_of_order_streaming()
13+
))
1514
.launch(app);
1615
}
1716

@@ -24,62 +23,97 @@ enum Route {
2423
#[route("/")]
2524
Home {},
2625

27-
#[route("/blog/:id/")]
28-
Blog { id: i32 },
26+
#[route("/:breed")]
27+
Breed { breed: String },
2928
}
3029

3130
#[component]
32-
fn Blog(id: i32) -> Element {
31+
fn Home() -> Element {
3332
rsx! {
34-
Link { to: Route::Home {}, "Go to counter" }
35-
table {
36-
tbody {
37-
for _ in 0..id {
38-
tr {
39-
for _ in 0..id {
40-
td { "hello world!" }
41-
}
42-
}
43-
}
44-
}
33+
Link { to: Route::Breed { breed: "hound".to_string() }, "Hound" }
34+
}
35+
}
36+
37+
#[component]
38+
fn Breed(breed: String) -> Element {
39+
rsx! {
40+
BreedGallery { breed: "{breed}", slow: false }
41+
SuspenseBoundary {
42+
fallback: |_| rsx! { "Loading..." },
43+
DoesNotSuspend {}
44+
BreedGallery { breed, slow: true }
4545
}
4646
}
4747
}
4848

4949
#[component]
50-
fn Home() -> Element {
51-
let mut count = use_signal(|| 0);
52-
let mut text = use_signal(|| "...".to_string());
50+
fn DoesNotSuspend() -> Element {
51+
rsx! { "404" }
52+
}
53+
54+
#[derive(serde::Deserialize, serde::Serialize)]
55+
struct BreedResponse {
56+
message: Vec<String>,
57+
}
58+
59+
#[component]
60+
fn BreedGallery(breed: ReadOnlySignal<String>, slow: bool) -> Element {
61+
// use_server_future is very similar to use_resource, but the value returned from the future
62+
// must implement Serialize and Deserialize and it is automatically suspended
63+
let response = use_server_future(move || async move {
64+
if slow {
65+
#[cfg(feature = "server")]
66+
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
67+
}
68+
#[cfg(feature = "server")]
69+
{
70+
use http::StatusCode;
71+
let context = server_context();
72+
let mut write = context.response_parts_mut();
73+
write.status = StatusCode::NOT_FOUND;
74+
write.extensions.insert("error???");
75+
write.version = http::Version::HTTP_2;
76+
write
77+
.headers
78+
.insert("x-custom-header", http::HeaderValue::from_static("hello"));
79+
}
80+
// The future will run on the server during SSR and then get sent to the client
81+
reqwest::Client::new()
82+
.get(format!("https://dog.ceo/api/breed/{breed}/images"))
83+
.send()
84+
.await
85+
// reqwest::Result does not implement Serialize, so we need to map it to a string which
86+
// can be serialized
87+
.map_err(|err| err.to_string())?
88+
.json::<BreedResponse>()
89+
.await
90+
.map_err(|err| err.to_string())
91+
// use_server_future calls `suspend` internally, so you don't need to call it manually, but you
92+
// do need to bubble up the suspense variant with `?`
93+
})?;
94+
95+
// If the future was still pending, it would have returned suspended with the `?` above
96+
// we can unwrap the None case here to get the inner result
97+
let response_read = response.read();
98+
let response = response_read.as_ref().unwrap();
5399

100+
// Then you can just handle the happy path with the resolved future
54101
rsx! {
55-
Link { to: Route::Blog { id: count() }, "Go to blog" }
56102
div {
57-
h1 { "High-Five counter: {count}" }
58-
button { onclick: move |_| count += 1, "Up high!" }
59-
button { onclick: move |_| count -= 1, "Down low!" }
60-
button {
61-
onclick: move |_| async move {
62-
if let Ok(data) = get_server_data().await {
63-
println!("Client received: {}", data);
64-
text.set(data.clone());
65-
post_server_data(data).await.unwrap();
103+
display: "flex",
104+
flex_direction: "row",
105+
match response {
106+
Ok(urls) => rsx! {
107+
for image in urls.message.iter().take(3) {
108+
img {
109+
src: "{image}",
110+
width: "100px",
111+
height: "100px",
112+
}
66113
}
67114
},
68-
"Run server function!"
115+
Err(err) => rsx! { "Failed to fetch response: {err}" },
69116
}
70-
"Server said: {text}"
71117
}
72118
}
73119
}
74-
75-
#[server(PostServerData)]
76-
async fn post_server_data(data: String) -> Result<(), ServerFnError> {
77-
println!("Server received: {}", data);
78-
79-
Ok(())
80-
}
81-
82-
#[server(GetServerData)]
83-
async fn get_server_data() -> Result<String, ServerFnError> {
84-
Ok("Hello from the server!".to_string())
85-
}
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
[package]
2-
name = "dioxus-streaming-context"
2+
name = "dioxus-fullstack-hooks"
33
authors = ["Jonathan Kelley", "Evan Almloff"]
44
version = { workspace = true }
55
edition = "2021"
6-
description = "Fullstack streaming status context for Dioxus"
6+
description = "Hooks for serializing futures, values in dioxus-fullstack and other utilities"
77
license = "MIT OR Apache-2.0"
88
repository = "https://github.com/DioxusLabs/dioxus/"
99
homepage = "https://dioxuslabs.com"
@@ -12,8 +12,18 @@ resolver = "2"
1212

1313
[dependencies]
1414
dioxus-core = { workspace = true }
15-
dioxus-signals.workspace = true
15+
dioxus-signals = { workspace = true }
16+
dioxus-hooks = { workspace = true }
17+
dioxus-web = { workspace = true, optional = true }
1618
futures-channel = { workspace = true }
19+
serde = { workspace = true }
20+
21+
[dev-dependencies]
22+
dioxus-fullstack = { workspace = true, features = ["server"] }
23+
24+
[features]
25+
web = ["dep:dioxus-web"]
26+
server = []
1727

1828
[package.metadata.docs.rs]
1929
cargo-args = ["-Zunstable-options", "-Zrustdoc-scrape-examples"]

packages/fullstack-hooks/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Dioxus Streaming Context
2+
3+
This crate provides a context for [`dioxus-fullstack`](https://crates.io/crates/dioxus-fullstack) about the context of the html stream. If streaming rendering is enabled, the context can be used to check if the first http chunk has been sent and the response metadata cannot be changed.
4+
5+
## Usage
6+
7+
```rust
8+
todo
9+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
mod server_cached;
2+
pub use server_cached::*;
3+
mod server_future;
4+
pub use server_future::*;

packages/fullstack/src/hooks/server_cached.rs renamed to packages/fullstack-hooks/src/hooks/server_cached.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use dioxus_lib::prelude::use_hook;
1+
use dioxus_core::prelude::use_hook;
22
use serde::{de::DeserializeOwned, Serialize};
33

44
/// This allows you to send data from the server to the client. The data is serialized into the HTML on the server and hydrated on the client.
@@ -34,7 +34,7 @@ pub(crate) fn server_cached<O: 'static + Clone + Serialize + DeserializeOwned>(
3434
) -> O {
3535
#[cfg(feature = "server")]
3636
{
37-
let serialize = crate::html_storage::serialize_context();
37+
let serialize = html_storage::serialize_context();
3838
let data = value();
3939
serialize.push(&data, location);
4040
data

packages/fullstack/src/hooks/server_future.rs renamed to packages/fullstack-hooks/src/hooks/server_future.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use dioxus_lib::prelude::*;
1+
use dioxus_core::prelude::{suspend, use_hook, RenderError};
2+
use dioxus_hooks::*;
3+
use dioxus_signals::Readable;
24
use serde::{de::DeserializeOwned, Serialize};
35
use std::future::Future;
46

packages/fullstack-hooks/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![warn(missing_docs)]
2+
#![doc = include_str!("../README.md")]
3+
4+
mod hooks;
5+
pub use hooks::*;
6+
mod streaming;
7+
pub use streaming::*;

0 commit comments

Comments
 (0)