Merge branch 'master' into intigrate-collect-assets

This commit is contained in:
Evan Almloff committed 2023-12-08 08:49:17 -06:00
commit 66e2c02bf7
168 files changed
+3727 -858

No files matched your search

@@ -372,15 +372,65 @@ fn apply_request_parts_to_response<B>(
}
}
/// SSR renderer handler for Axum
pub async fn render_handler<P: Clone + serde::Serialize + Send + Sync + 'static>(
State((cfg, ssr_state)): State<(ServeConfig<P>, SSRState)>,
/// SSR renderer handler for Axum with added context injection.
///
/// # Example
/// ```rust,no_run
/// #![allow(non_snake_case)]
/// use std::sync::{Arc, Mutex};
///
/// use axum::routing::get;
/// use dioxus::prelude::*;
/// use dioxus_fullstack::{axum_adapter::render_handler_with_context, prelude::*};
///
/// fn app(cx: Scope) -> Element {
/// render! {
/// "hello!"
/// }
/// }
///
/// #[tokio::main]
/// async fn main() {
/// let cfg = ServeConfigBuilder::new(app, ())
/// .assets_path("dist")
/// .build();
/// let ssr_state = SSRState::new(&cfg);
///
/// // This could be any state you want to be accessible from your server
/// // functions using `[DioxusServerContext::get]`.
/// let state = Arc::new(Mutex::new("state".to_string()));
///
/// let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080));
/// axum::Server::bind(&addr)
/// .serve(
/// axum::Router::new()
/// // Register server functions, etc.
/// // Note you probably want to use `register_server_fns_with_handler`
/// // to inject the context into server functions running outside
/// // of an SSR render context.
/// .fallback(get(render_handler_with_context).with_state((
/// move |ctx| ctx.insert(state.clone()).unwrap(),
/// cfg,
/// ssr_state,
/// )))
/// .into_make_service(),
/// )
/// .await
/// .unwrap();
/// }
/// ```
pub async fn render_handler_with_context<
P: Clone + serde::Serialize + Send + Sync + 'static,
F: FnMut(&mut DioxusServerContext),
>(
State((mut inject_context, cfg, ssr_state)): State<(F, ServeConfig<P>, SSRState)>,
request: Request<Body>,
) -> impl IntoResponse {
let (parts, _) = request.into_parts();
let url = parts.uri.path_and_query().unwrap().to_string();
let parts: Arc<RwLock<http::request::Parts>> = Arc::new(RwLock::new(parts.into()));
let server_context = DioxusServerContext::new(parts.clone());
let mut server_context = DioxusServerContext::new(parts.clone());
inject_context(&mut server_context);
match ssr_state.render(url, &cfg, &server_context).await {
Ok(rendered) => {
@@ -398,6 +448,14 @@ pub async fn render_handler<P: Clone + serde::Serialize + Send + Sync + 'static>
}
}
/// SSR renderer handler for Axum
pub async fn render_handler<P: Clone + serde::Serialize + Send + Sync + 'static>(
State((cfg, ssr_state)): State<(ServeConfig<P>, SSRState)>,
request: Request<Body>,
) -> impl IntoResponse {
render_handler_with_context(State((|_: &mut _| (), cfg, ssr_state)), request).await
}
fn report_err<E: std::fmt::Display>(e: E) -> Response<BoxBody> {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
+19 -19
View File
@@ -89,26 +89,26 @@ impl Service for ServerFnHandler {
let parts = Arc::new(RwLock::new(parts));
// Because the future returned by `server_fn_handler` is `Send`, and the future returned by this function must be send, we need to spawn a new runtime
let (resp_tx, resp_rx) = tokio::sync::oneshot::channel();
let pool = get_local_pool();
pool.spawn_pinned({
let function = function.clone();
let mut server_context = server_context.clone();
server_context.parts = parts;
move || async move {
let data = match function.encoding() {
Encoding::Url | Encoding::Cbor => &body,
Encoding::GetJSON | Encoding::GetCBOR => &query,
};
let server_function_future = function.call((), data);
let server_function_future =
ProvideServerContext::new(server_function_future, server_context.clone());
let resp = server_function_future.await;
resp_tx.send(resp).unwrap();
}
});
let result = resp_rx.await.unwrap();
let result = pool
.spawn_pinned({
let function = function.clone();
let mut server_context = server_context.clone();
server_context.parts = parts;
move || async move {
let data = match function.encoding() {
Encoding::Url | Encoding::Cbor => &body,
Encoding::GetJSON | Encoding::GetCBOR => &query,
};
let server_function_future = function.call((), data);
let server_function_future = ProvideServerContext::new(
server_function_future,
server_context.clone(),
);
server_function_future.await
}
})
.await?;
let mut res = http::Response::builder();
// Set the headers from the server context