Add fullstack platform to serve and build commands

This commit is contained in:
Evan Almloff committed 2023-08-18 13:55:00 -05:00
1 parent f652474a6e
commit bd743fa2f9
7 files changed
+209 -49

No files matched your search

+60 -45
View File
@@ -1,4 +1,5 @@
use crate::{
cfg::ConfigOptsServe,
server::{
output::{print_console_info, PrettierOptions},
setup_file_watcher, setup_file_watcher_hot_reload,
@@ -19,7 +20,16 @@ use tokio::sync::broadcast::{self};
#[cfg(feature = "plugin")]
use plugin::PluginManager;
pub async fn startup(config: CrateConfig) -> Result<()> {
use super::Platform;
pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> {
startup_with_platform::<DesktopPlatform>(config, serve).await
}
pub(crate) async fn startup_with_platform<P: Platform + Send + 'static>(
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::<P>(config, serve).await?,
false => serve_default::<P>(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<Child> = RwLock::new(child);
async fn serve_default<P: Platform + Send + 'static>(
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<P: Platform + Send + 'static>(
config: CrateConfig,
serve: &ConfigOptsServe,
) -> Result<()> {
let platform = RwLock::new(P::start(&config, serve)?);
// Setup hot reload
let FileMapBuildResult { map, errors } =
FileMap::<HtmlCtx>::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)
Ok(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)?;
@@ -246,3 +227,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<Self> {
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<BuildResult> {
self.currently_running_child.kill()?;
let (child, result) = start_desktop(&config)?;
self.currently_running_child = child;
Ok(result)
}
}
+72
View File
@@ -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::<FullstackPlatform>(config, serve).await
}
struct FullstackPlatform {
serve: ConfigOptsServe,
desktop: desktop::DesktopPlatform,
}
impl Platform for FullstackPlatform {
fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result<Self>
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<crate::BuildResult> {
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)
}
+9 -1
View File
@@ -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<F: Fn() -> Result<BuildResult> + Send + '
Ok(watcher)
}
pub(crate) trait Platform {
fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result<Self>
where
Self: Sized;
fn rebuild(&mut self, config: &CrateConfig) -> Result<BuildResult>;
}
+2 -2
View File
@@ -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,