Merge branch 'master' into intigrate-collect-assets
This commit is contained in:
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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in new issue
Block a user