(
+ config: CrateConfig,
+ serve: &ConfigOptsServe,
+) -> Result<()> {
// ctrl-c shutdown checker
let _crate_config = config.clone();
let _ = ctrlc::set_handler(move || {
@@ -29,17 +39,19 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
});
match config.hot_reload {
- true => serve_hot_reload(config).await?,
- false => serve_default(config).await?,
+ true => serve_hot_reload::(config, serve).await?,
+ false => serve_default::
(config, serve).await?,
}
Ok(())
}
/// Start the server without hot reload
-pub async fn serve_default(config: CrateConfig) -> Result<()> {
- let (child, first_build_result) = start_desktop(&config)?;
- let currently_running_child: RwLock = RwLock::new(child);
+async fn serve_default(
+ config: CrateConfig,
+ serve: &ConfigOptsServe,
+) -> Result<()> {
+ let platform = RwLock::new(P::start(&config, serve)?);
log::info!("🚀 Starting development server...");
@@ -49,49 +61,29 @@ pub async fn serve_default(config: CrateConfig) -> Result<()> {
{
let config = config.clone();
- move || {
- let mut current_child = currently_running_child.write().unwrap();
- current_child.kill()?;
- let (child, result) = start_desktop(&config)?;
- *current_child = child;
- Ok(result)
- }
+ move || platform.write().unwrap().rebuild(&config)
},
&config,
None,
)
.await?;
- // Print serve info
- print_console_info(
- &config,
- PrettierOptions {
- changed: vec![],
- warnings: first_build_result.warnings,
- elapsed_time: first_build_result.elapsed_time,
- },
- None,
- );
-
std::future::pending::<()>().await;
Ok(())
}
-/// Start the server without hot reload
-
/// Start dx serve with hot reload
-pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
- let (_, first_build_result) = start_desktop(&config)?;
-
- println!("🚀 Starting development server...");
+async fn serve_hot_reload(
+ config: CrateConfig,
+ serve: &ConfigOptsServe,
+) -> Result<()> {
+ let platform = RwLock::new(P::start(&config, serve)?);
// Setup hot reload
let FileMapBuildResult { map, errors } =
FileMap::::create(config.crate_dir.clone()).unwrap();
- println!("🚀 Starting development server...");
-
for err in errors {
log::error!("{}", err);
}
@@ -119,24 +111,13 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
for channel in &mut *channels.lock().unwrap() {
send_msg(HotReloadMsg::Shutdown, channel);
}
- Ok(start_desktop(&config)?.1)
+ platform.write().unwrap().rebuild(&config)
}
},
None,
)
.await?;
- // Print serve info
- print_console_info(
- &config,
- PrettierOptions {
- changed: vec![],
- warnings: first_build_result.warnings,
- elapsed_time: first_build_result.elapsed_time,
- },
- None,
- );
-
clear_paths();
match LocalSocketListener::bind("@dioxusin") {
@@ -228,7 +209,7 @@ fn send_msg(msg: HotReloadMsg, channel: &mut impl std::io::Write) -> bool {
}
}
-pub fn start_desktop(config: &CrateConfig) -> Result<(Child, BuildResult)> {
+fn start_desktop(config: &CrateConfig) -> Result<(Child, BuildResult)> {
// Run the desktop application
let result = crate::builder::build_desktop(config, true)?;
@@ -249,3 +230,37 @@ pub fn start_desktop(config: &CrateConfig) -> Result<(Child, BuildResult)> {
}
}
}
+
+pub(crate) struct DesktopPlatform {
+ currently_running_child: Child,
+}
+
+impl Platform for DesktopPlatform {
+ fn start(config: &CrateConfig, _serve: &ConfigOptsServe) -> Result {
+ let (child, first_build_result) = start_desktop(config)?;
+
+ log::info!("🚀 Starting development server...");
+
+ // Print serve info
+ print_console_info(
+ config,
+ PrettierOptions {
+ changed: vec![],
+ warnings: first_build_result.warnings,
+ elapsed_time: first_build_result.elapsed_time,
+ },
+ None,
+ );
+
+ Ok(Self {
+ currently_running_child: child,
+ })
+ }
+
+ fn rebuild(&mut self, config: &CrateConfig) -> Result {
+ self.currently_running_child.kill()?;
+ let (child, result) = start_desktop(config)?;
+ self.currently_running_child = child;
+ Ok(result)
+ }
+}
diff --git a/packages/cli/src/server/fullstack/mod.rs b/packages/cli/src/server/fullstack/mod.rs
new file mode 100644
index 000000000..16ab31c44
--- /dev/null
+++ b/packages/cli/src/server/fullstack/mod.rs
@@ -0,0 +1,72 @@
+use crate::{
+ cfg::{ConfigOptsBuild, ConfigOptsServe},
+ CrateConfig, Result,
+};
+
+use super::{desktop, Platform};
+
+pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
+ desktop::startup_with_platform::(config, serve).await
+}
+
+struct FullstackPlatform {
+ serve: ConfigOptsServe,
+ desktop: desktop::DesktopPlatform,
+}
+
+impl Platform for FullstackPlatform {
+ fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result
+ where
+ Self: Sized,
+ {
+ {
+ build_web(serve.clone())?;
+ }
+
+ let mut desktop_config = config.clone();
+ let desktop_feature = serve.server_feature.clone();
+ let features = &mut desktop_config.features;
+ match features {
+ Some(features) => {
+ features.push(desktop_feature);
+ }
+ None => desktop_config.features = Some(vec![desktop_feature]),
+ };
+ let desktop = desktop::DesktopPlatform::start(&desktop_config, serve)?;
+
+ Ok(Self {
+ desktop,
+ serve: serve.clone(),
+ })
+ }
+
+ fn rebuild(&mut self, crate_config: &CrateConfig) -> Result {
+ build_web(self.serve.clone())?;
+ {
+ let mut desktop_config = crate_config.clone();
+ let desktop_feature = self.serve.server_feature.clone();
+ let features = &mut desktop_config.features;
+ match features {
+ Some(features) => {
+ features.push(desktop_feature);
+ }
+ None => desktop_config.features = Some(vec![desktop_feature]),
+ };
+ self.desktop.rebuild(&desktop_config)
+ }
+ }
+}
+
+fn build_web(serve: ConfigOptsServe) -> Result<()> {
+ let mut web_config: ConfigOptsBuild = serve.into();
+ let web_feature = web_config.client_feature.clone();
+ let features = &mut web_config.features;
+ match features {
+ Some(features) => {
+ features.push(web_feature);
+ }
+ None => web_config.features = Some(vec![web_feature]),
+ };
+ web_config.platform = Some(crate::cfg::Platform::Web);
+ crate::cli::build::Build { build: web_config }.build(None)
+}
diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs
index 19dc44b75..1571a198e 100644
--- a/packages/cli/src/server/mod.rs
+++ b/packages/cli/src/server/mod.rs
@@ -1,4 +1,4 @@
-use crate::{BuildResult, CrateConfig, Result};
+use crate::{cfg::ConfigOptsServe, BuildResult, CrateConfig, Result};
use cargo_metadata::diagnostic::Diagnostic;
use dioxus_core::Template;
@@ -14,6 +14,7 @@ use tokio::sync::broadcast::Sender;
mod output;
use output::*;
pub mod desktop;
+pub mod fullstack;
pub mod web;
/// Sets up a file watcher
@@ -180,3 +181,10 @@ async fn setup_file_watcher_hot_reload Result + Send + '
Ok(watcher)
}
+
+pub(crate) trait Platform {
+ fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result
+ where
+ Self: Sized;
+ fn rebuild(&mut self, config: &CrateConfig) -> Result;
+}
diff --git a/packages/cli/src/server/web/mod.rs b/packages/cli/src/server/web/mod.rs
index e08d2297a..7f09dca6c 100644
--- a/packages/cli/src/server/web/mod.rs
+++ b/packages/cli/src/server/web/mod.rs
@@ -5,7 +5,7 @@ use crate::{
output::{print_console_info, PrettierOptions, WebServerInfo},
setup_file_watcher, setup_file_watcher_hot_reload,
},
- BuildResult, CrateConfig, Result,
+ BuildResult, CrateConfig, Result, WebHttpsConfig,
};
use axum::{
body::{Full, HttpBody},
@@ -67,7 +67,7 @@ pub async fn startup(port: u16, config: CrateConfig, start_browser: bool) -> Res
}
/// Start the server without hot reload
-pub async fn serve_default(
+async fn serve_default(
ip: String,
port: u16,
config: CrateConfig,
@@ -128,7 +128,7 @@ pub async fn serve_default(
}
/// Start dx serve with hot reload
-pub async fn serve_hot_reload(
+async fn serve_hot_reload(
ip: String,
port: u16,
config: CrateConfig,
@@ -218,67 +218,12 @@ async fn get_rustls(config: &CrateConfig) -> Result