From be1343fa88733daf0ee80ba93fe9cbfe43c406c7 Mon Sep 17 00:00:00 2001 From: Gentle Date: Thu, 26 Jan 2023 19:04:59 +0100 Subject: [PATCH] refactor to eliminate duplicate code (#380) --- integrations/axum/src/lib.rs | 173 +---------------------------------- 1 file changed, 1 insertion(+), 172 deletions(-) diff --git a/integrations/axum/src/lib.rs b/integrations/axum/src/lib.rs index f081f62c1..371a03241 100644 --- a/integrations/axum/src/lib.rs +++ b/integrations/axum/src/lib.rs @@ -442,178 +442,7 @@ pub fn render_app_to_stream( where IV: IntoView, { - move |req: Request| { - Box::pin({ - let options = options.clone(); - let app_fn = app_fn.clone(); - let default_res_options = ResponseOptions::default(); - let res_options2 = default_res_options.clone(); - let res_options3 = default_res_options.clone(); - - async move { - // Need to get the path and query string of the Request - // For reasons that escape me, if the incoming URI protocol is https, it provides the absolute URI - // if http, it returns a relative path. Adding .path() seems to make it explicitly return the relative uri - let path = req.uri().path_and_query().unwrap().as_str(); - - let full_path = format!("http://leptos.dev{path}"); - - let pkg_path = &options.site_pkg_dir; - let output_name = &options.output_name; - - // Because wasm-pack adds _bg to the end of the WASM filename, and we want to mantain compatibility with it's default options - // we add _bg to the wasm files if cargo-leptos doesn't set the env var LEPTOS_OUTPUT_NAME - // Otherwise we need to add _bg because wasm_pack always does. This is not the same as options.output_name, which is set regardless - let mut wasm_output_name = output_name.clone(); - if std::env::var("LEPTOS_OUTPUT_NAME").is_err() { - wasm_output_name.push_str("_bg"); - } - - let site_ip = &options.site_address.ip().to_string(); - let reload_port = options.reload_port; - - let leptos_autoreload = match std::env::var("LEPTOS_WATCH").is_ok() { - true => format!( - r#" - - "# - ), - false => "".to_string(), - }; - - let head = format!( - r#" - - - - - - - - {leptos_autoreload} - "# - ); - let tail = ""; - - let (mut tx, rx) = futures::channel::mpsc::channel(8); - - spawn_blocking({ - let app_fn = app_fn.clone(); - move || { - tokio::runtime::Runtime::new() - .expect("couldn't spawn runtime") - .block_on({ - let app_fn = app_fn.clone(); - async move { - tokio::task::LocalSet::new() - .run_until(async { - let app = { - let full_path = full_path.clone(); - let req_parts = generate_request_parts(req).await; - move |cx| { - let integration = ServerIntegration { - path: full_path.clone(), - }; - provide_context( - cx, - RouterIntegrationContext::new(integration), - ); - provide_context(cx, MetaContext::new()); - provide_context(cx, req_parts); - provide_context(cx, default_res_options); - app_fn(cx).into_view(cx) - } - }; - - let (bundle, runtime, scope) = - render_to_stream_with_prefix_undisposed( - app, - |cx| { - let head = use_context::(cx) - .map(|meta| meta.dehydrate()) - .unwrap_or_default(); - format!("{head}").into() - }, - ); - let mut shell = Box::pin(bundle); - while let Some(fragment) = shell.next().await { - _ = tx.send(fragment).await; - } - - // Extract the value of ResponseOptions from here - let cx = Scope { runtime, id: scope }; - let res_options = - use_context::(cx).unwrap(); - - let new_res_parts = res_options.0.read().await.clone(); - - let mut writable = res_options2.0.write().await; - *writable = new_res_parts; - - runtime.dispose(); - - tx.close_channel(); - }) - .await; - } - }); - } - }); - - let mut stream = Box::pin( - futures::stream::once(async move { head.clone() }) - .chain(rx) - .chain(futures::stream::once(async { tail.to_string() })) - .map(|html| Ok(Bytes::from(html))), - ); - - // Get the first, second, and third chunks in the stream, which renders the app shell, and thus allows Resources to run - let first_chunk = stream.next().await; - let second_chunk = stream.next().await; - let third_chunk = stream.next().await; - - // Extract the resources now that they've been rendered - let res_options = res_options3.0.read().await; - - let complete_stream = futures::stream::iter([ - first_chunk.unwrap(), - second_chunk.unwrap(), - third_chunk.unwrap(), - ]) - .chain(stream); - - let mut res = Response::new(StreamBody::new( - Box::pin(complete_stream) as PinnedHtmlStream - )); - - if let Some(status) = res_options.status { - *res.status_mut() = status - } - let mut res_headers = res_options.headers.clone(); - res.headers_mut().extend(res_headers.drain()); - - res - } - }) - } + render_app_to_stream_with_context(options, |_| {}, app_fn) } /// Returns an Axum [Handler](axum::handler::Handler) that listens for a `GET` request and tries