mirror of
https://github.com/DioxusLabs/dioxus
synced 2025-02-16 13:48:26 +00:00
Simplify the launch builder (#2967)
* improve documentation for the fullstack server context * Add a section about axum integration to the crate root docs * make serve_dioxus_application accept the cfg builder directly * remove unused server_fn module * improve fullstack config docs * improve documentation for the server function macro * fix axum router extension link * Fix doc tests * Fix launch builder * Simplify the launch builder * don't re-export launch in the prelude * refactor fullstack launch * Fix fullstack launch builder * Update static generation with the new builder api * fix some formatting/overly broad launch replacements * fix custom menu example * fix fullstack/static generation examples * Fix static generation launch * A few small formatting fixes * Fix a few doc tests * implement LaunchConfig for serve configs * fix fullstack launch with separate web and server launch methods * fix check with all features * dont expose inner core module * clippy and check * fix readme --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
parent
2d7bef44e8
commit
20d146d9bd
126 changed files with 618 additions and 989 deletions
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -15,7 +15,7 @@ mod components {
|
||||||
mod api;
|
mod api;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
head::Link {
|
head::Link {
|
||||||
rel: "stylesheet",
|
rel: "stylesheet",
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dioxus::desktop::{Config, WindowBuilder};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(Config::new().with_window(WindowBuilder::new().with_resizable(true)))
|
.with_cfg(Config::new().with_window(WindowBuilder::new().with_resizable(true)))
|
||||||
.launch(app)
|
.launch(app)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
launch(|| rsx! { Router::<Route> {} });
|
dioxus::launch(|| rsx! { Router::<Route> {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Routable)]
|
#[derive(Clone, Routable)]
|
||||||
|
|
|
@ -2,7 +2,7 @@ use dioxus::prelude::*;
|
||||||
use wifiscanner::Wifi;
|
use wifiscanner::Wifi;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app)
|
dioxus::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_scan() -> Status {
|
fn perform_scan() -> Status {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::{collections::VecDeque, fmt::Debug, rc::Rc};
|
||||||
const STYLE: &str = asset!("./examples/assets/events.css");
|
const STYLE: &str = asset!("./examples/assets/events.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use async_std::task::sleep;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/calculator.css");
|
const STYLE: &str = asset!("./examples/assets/calculator.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(desktop!({
|
.with_cfg(desktop!({
|
||||||
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dioxus::html::MouseEvent;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(
|
.with_cfg(
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
WindowBuilder::new()
|
WindowBuilder::new()
|
||||||
|
|
|
@ -8,7 +8,7 @@ use web_time::Instant;
|
||||||
const STYLE: &str = asset!("./examples/assets/clock.css");
|
const STYLE: &str = asset!("./examples/assets/clock.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/roulette.css");
|
const STYLE: &str = asset!("./examples/assets/roulette.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/counter.css");
|
const STYLE: &str = asset!("./examples/assets/counter.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::new()
|
dioxus::LaunchBuilder::new()
|
||||||
.with_cfg(desktop!({
|
.with_cfg(desktop!({
|
||||||
use dioxus::desktop::{LogicalSize, WindowBuilder};
|
use dioxus::desktop::{LogicalSize, WindowBuilder};
|
||||||
dioxus::desktop::Config::default()
|
dioxus::desktop::Config::default()
|
||||||
|
|
|
@ -14,7 +14,7 @@ static ASSET_PATH: &str = "examples/assets/logo.png";
|
||||||
static ASSET_PATH: &str = asset!("examples/assets/logo.png".format(ImageType::Avif));
|
static ASSET_PATH: &str = asset!("examples/assets/logo.png".format(ImageType::Avif));
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::new()
|
dioxus::LaunchBuilder::new()
|
||||||
.with_cfg(
|
.with_cfg(
|
||||||
dioxus::desktop::Config::new().with_custom_index(
|
dioxus::desktop::Config::new().with_custom_index(
|
||||||
r#"
|
r#"
|
||||||
|
|
|
@ -28,7 +28,7 @@ fn main() {
|
||||||
let config = dioxus::desktop::Config::new().with_menu(menu);
|
let config = dioxus::desktop::Config::new().with_menu(menu);
|
||||||
|
|
||||||
// Launch the app with the custom menu
|
// Launch the app with the custom menu
|
||||||
LaunchBuilder::new().with_cfg(config).launch(app)
|
dioxus::LaunchBuilder::new().with_cfg(config).launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dioxus::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/custom_assets.css");
|
const STYLE: &str = asset!("./examples/assets/custom_assets.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| rsx! { Router::<Route> {} });
|
dioxus::launch(|| rsx! { Router::<Route> {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// You can use an ErrorBoundary to catch errors in children and display a warning
|
/// You can use an ErrorBoundary to catch errors in children and display a warning
|
||||||
|
|
|
@ -7,7 +7,7 @@ use async_std::task::sleep;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dioxus::{html::HasFileData, prelude::dioxus_elements::FileEngine};
|
||||||
const STYLE: &str = asset!("./examples/assets/file_upload.css");
|
const STYLE: &str = asset!("./examples/assets/file_upload.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UploadedFile {
|
struct UploadedFile {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/flat_router.css");
|
const STYLE: &str = asset!("./examples/assets/flat_router.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
head::Link { rel: "stylesheet", href: STYLE }
|
head::Link { rel: "stylesheet", href: STYLE }
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dioxus::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@ fn main() {
|
||||||
// Set the url of the server where server functions are hosted.
|
// Set the url of the server where server functions are hosted.
|
||||||
#[cfg(not(feature = "server"))]
|
#[cfg(not(feature = "server"))]
|
||||||
dioxus::fullstack::prelude::server_fn::client::set_server_url("http://127.0.0.1:8080");
|
dioxus::fullstack::prelude::server_fn::client::set_server_url("http://127.0.0.1:8080");
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app() -> Element {
|
pub fn app() -> Element {
|
||||||
|
|
|
@ -50,5 +50,5 @@ fn main() {
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::fullstack()
|
dioxus::LaunchBuilder::new()
|
||||||
.with_cfg(server_only!(ServeConfig::builder().incremental(
|
.with_cfg(server_only!(ServeConfig::builder().incremental(
|
||||||
IncrementalRendererConfig::default()
|
IncrementalRendererConfig::default()
|
||||||
.invalidate_after(std::time::Duration::from_secs(120)),
|
.invalidate_after(std::time::Duration::from_secs(120)),
|
||||||
|
|
|
@ -37,5 +37,5 @@ pub async fn test_stream() -> Result<TextStream, ServerFnError> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app)
|
dioxus::launch(app)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use async_std::task::sleep;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use dioxus::prelude::*;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -13,7 +13,7 @@ static COUNT: GlobalSignal<i32> = Signal::global(|| 0);
|
||||||
static DOUBLED_COUNT: GlobalMemo<i32> = Memo::global(|| COUNT() * 2);
|
static DOUBLED_COUNT: GlobalMemo<i32> = Memo::global(|| COUNT() * 2);
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -19,7 +19,7 @@ use dioxus::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dioxus::desktop::Config;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(Config::new().with_prerendered({
|
.with_cfg(Config::new().with_prerendered({
|
||||||
// We build the dom a first time, then pre-render it to HTML
|
// We build the dom a first time, then pre-render it to HTML
|
||||||
let pre_rendered_dom = VirtualDom::prebuilt(app);
|
let pre_rendered_dom = VirtualDom::prebuilt(app);
|
||||||
|
|
|
@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use serde_json::{json, Error};
|
use serde_json::{json, Error};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app)
|
dioxus::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/links.css");
|
const STYLE: &str = asset!("./examples/assets/links.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn main() -> Result<()> {
|
||||||
|
|
||||||
// Right now we're going through dioxus-desktop but we'd like to go through dioxus-mobile
|
// Right now we're going through dioxus-desktop but we'd like to go through dioxus-mobile
|
||||||
// That will seed the index.html with some fixes that prevent the page from scrolling/zooming etc
|
// That will seed the index.html with some fixes that prevent the page from scrolling/zooming etc
|
||||||
LaunchBuilder::mobile()
|
dioxus::LaunchBuilder::mobile()
|
||||||
.with_cfg(
|
.with_cfg(
|
||||||
// Note that we have to disable the viewport goofiness of the browser.
|
// Note that we have to disable the viewport goofiness of the browser.
|
||||||
// Dioxus_mobile should do this for us
|
// Dioxus_mobile should do this for us
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,9 @@ use dioxus::desktop::{
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop().with_cfg(make_config()).launch(app);
|
dioxus::LaunchBuilder::desktop()
|
||||||
|
.with_cfg(make_config())
|
||||||
|
.launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@ fn main() {
|
||||||
wasm_logger::init(wasm_logger::Config::default());
|
wasm_logger::init(wasm_logger::Config::default());
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::rc::Rc;
|
||||||
use dioxus::{html::geometry::euclid::Rect, prelude::*};
|
use dioxus::{html::geometry::euclid::Rect, prelude::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/radio.css");
|
const STYLE: &str = asset!("./examples/assets/radio.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use dioxus::prelude::*;
|
||||||
use dioxus_elements::geometry::euclid::Size2D;
|
use dioxus_elements::geometry::euclid::Size2D;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use dioxus::prelude::*;
|
||||||
const STYLE: &str = asset!("./examples/assets/router.css");
|
const STYLE: &str = asset!("./examples/assets/router.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
head::Link { rel: "stylesheet", href: STYLE }
|
head::Link { rel: "stylesheet", href: STYLE }
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
|
|
|
@ -15,7 +15,7 @@ enum Route {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
//! - Allow top-level fragments
|
//! - Allow top-level fragments
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app)
|
dioxus::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
use core::{fmt, str::FromStr};
|
use core::{fmt, str::FromStr};
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -9,7 +9,7 @@ use dioxus::desktop::use_global_shortcut;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use async_std::task::sleep;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Launch the router, using our `Route` component as the generic type
|
// launch the router, using our `Route` component as the generic type
|
||||||
// This will automatically boot the app to "/" unless otherwise specified
|
// This will automatically boot the app to "/" unless otherwise specified
|
||||||
launch(|| rsx! { Router::<Route> {} });
|
dioxus::launch(|| rsx! { Router::<Route> {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// By default, the Routable derive will use the name of the variant as the route
|
/// By default, the Routable derive will use the name of the variant as the route
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
// Generate all routes and output them to the static path
|
// Generate all routes and output them to the static path
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::new()
|
dioxus::LaunchBuilder::new()
|
||||||
.with_cfg(dioxus::static_site_generation::Config::new().github_pages())
|
.with_cfg(dioxus::static_site_generation::Config::new().github_pages())
|
||||||
.launch(|| {
|
.launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
// Generate all routes and output them to the static path
|
// Generate all routes and output them to the static path
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
// Generate all routes and output them to the static path
|
// Generate all routes and output them to the static path
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||||
use futures_util::{future, stream, Stream, StreamExt};
|
use futures_util::{future, stream, Stream, StreamExt};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -15,7 +15,7 @@ use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::new()
|
dioxus::LaunchBuilder::new()
|
||||||
.with_cfg(desktop! {
|
.with_cfg(desktop! {
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
WindowBuilder::new()
|
WindowBuilder::new()
|
||||||
|
|
|
@ -10,7 +10,7 @@ use dioxus::prelude::*;
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(|| {
|
dioxus::launch(|| {
|
||||||
rsx! {
|
rsx! {
|
||||||
div { user_select: "none", webkit_user_select: "none", margin_left: "10%", margin_right: "10%",
|
div { user_select: "none", webkit_user_select: "none", margin_left: "10%", margin_right: "10%",
|
||||||
h1 { "Click die to generate a new value" }
|
h1 { "Click die to generate a new value" }
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::prelude::*;
|
||||||
const _STYLE: &str = asset!("public/tailwind.css");
|
const _STYLE: &str = asset!("public/tailwind.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app() -> Element {
|
pub fn app() -> Element {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::collections::HashMap;
|
||||||
const STYLE: &str = asset!("./examples/assets/todomvc.css");
|
const STYLE: &str = asset!("./examples/assets/todomvc.css");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy)]
|
#[derive(PartialEq, Eq, Clone, Copy)]
|
||||||
|
|
|
@ -16,13 +16,13 @@ fn main() {
|
||||||
// For the sake of this example, we will download the video file if it doesn't exist
|
// For the sake of this example, we will download the video file if it doesn't exist
|
||||||
ensure_video_is_loaded();
|
ensure_video_is_loaded();
|
||||||
|
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
// Any request to /videos will be handled by this handler
|
// Any request to /videos will be handled by this handler
|
||||||
use_asset_handler("videos", move |request, responder| {
|
use_asset_handler("videos", move |request, responder| {
|
||||||
// Using dioxus::spawn works, but is slower than a dedicated thread
|
// Using spawn works, but is slower than a dedicated thread
|
||||||
tokio::task::spawn(async move {
|
tokio::task::spawn(async move {
|
||||||
let video_file = PathBuf::from(VIDEO_PATH);
|
let video_file = PathBuf::from(VIDEO_PATH);
|
||||||
let mut file = tokio::fs::File::open(&video_file).await.unwrap();
|
let mut file = tokio::fs::File::open(&video_file).await.unwrap();
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::prelude::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -13,7 +13,7 @@ use dioxus::desktop::{window, Config, WindowBuilder};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(
|
.with_cfg(
|
||||||
Config::new().with_window(
|
Config::new().with_window(
|
||||||
WindowBuilder::new()
|
WindowBuilder::new()
|
||||||
|
|
|
@ -12,7 +12,7 @@ use dioxus::desktop::{Config, WindowCloseBehaviour};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(Config::new().with_close_behaviour(WindowCloseBehaviour::CloseWindow))
|
.with_cfg(Config::new().with_close_behaviour(WindowCloseBehaviour::CloseWindow))
|
||||||
.launch(app)
|
.launch(app)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch_desktop(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(app);
|
dioxus::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop().launch(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowPreferences {
|
struct WindowPreferences {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop().launch(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowPreferences {
|
struct WindowPreferences {
|
||||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
LaunchBuilder::desktop().launch(app);
|
dioxus::LaunchBuilder::desktop().launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WindowPreferences {
|
struct WindowPreferences {
|
||||||
|
|
|
@ -150,6 +150,49 @@ impl BuildRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub(crate) struct OpenArguments {
|
||||||
|
fullstack_address: Option<SocketAddr>,
|
||||||
|
devserver_addr: Option<SocketAddr>,
|
||||||
|
always_on_top: Option<bool>,
|
||||||
|
workspace: PathBuf,
|
||||||
|
asset_root: PathBuf,
|
||||||
|
app_title: String,
|
||||||
|
out_dir: PathBuf,
|
||||||
|
serve: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpenArguments {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub(crate) fn new(
|
||||||
|
serve: &ServeArguments,
|
||||||
|
fullstack_address: Option<SocketAddr>,
|
||||||
|
dioxus_crate: &DioxusCrate,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
devserver_addr: Some(serve.address.address()),
|
||||||
|
always_on_top: Some(serve.always_on_top.unwrap_or(true)),
|
||||||
|
serve: true,
|
||||||
|
fullstack_address,
|
||||||
|
workspace: dioxus_crate.workspace_dir().to_path_buf(),
|
||||||
|
asset_root: dioxus_crate.asset_dir().to_path_buf(),
|
||||||
|
app_title: dioxus_crate.dioxus_config.application.name.clone(),
|
||||||
|
out_dir: dioxus_crate.out_dir().to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub(crate) fn new_for_static_generation_build(dioxus_crate: &DioxusCrate) -> Self {
|
||||||
|
Self {
|
||||||
|
workspace: dioxus_crate.workspace_dir().to_path_buf(),
|
||||||
|
asset_root: dioxus_crate.asset_dir().to_path_buf(),
|
||||||
|
app_title: dioxus_crate.dioxus_config.application.name.clone(),
|
||||||
|
out_dir: dioxus_crate.out_dir().to_path_buf(),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct BuildResult {
|
pub(crate) struct BuildResult {
|
||||||
pub executable: PathBuf,
|
pub executable: PathBuf,
|
||||||
|
@ -158,20 +201,12 @@ pub(crate) struct BuildResult {
|
||||||
|
|
||||||
impl BuildResult {
|
impl BuildResult {
|
||||||
/// Open the executable if this is a native build
|
/// Open the executable if this is a native build
|
||||||
#[allow(clippy::too_many_arguments)]
|
pub fn open(&self, arguments: OpenArguments) -> std::io::Result<Option<Child>> {
|
||||||
pub fn open(
|
|
||||||
&self,
|
|
||||||
serve: &ServeArguments,
|
|
||||||
fullstack_address: Option<SocketAddr>,
|
|
||||||
workspace: &std::path::Path,
|
|
||||||
asset_root: &std::path::Path,
|
|
||||||
devserver_addr: SocketAddr,
|
|
||||||
app_title: String,
|
|
||||||
out_dir: PathBuf,
|
|
||||||
) -> std::io::Result<Option<Child>> {
|
|
||||||
match self.target_platform {
|
match self.target_platform {
|
||||||
TargetPlatform::Web => {
|
TargetPlatform::Web => {
|
||||||
tracing::info!(dx_src = ?TraceSrc::Dev, "Serving web app on http://{} 🎉", serve.address.address());
|
if let Some(address) = arguments.fullstack_address {
|
||||||
|
tracing::info!(dx_src = ?TraceSrc::Dev, "Serving web app on http://{} 🎉", address);
|
||||||
|
}
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
TargetPlatform::Desktop => {
|
TargetPlatform::Desktop => {
|
||||||
|
@ -181,7 +216,7 @@ impl BuildResult {
|
||||||
// shut this up for now - the web app will take priority in logging
|
// shut this up for now - the web app will take priority in logging
|
||||||
}
|
}
|
||||||
TargetPlatform::Liveview => {
|
TargetPlatform::Liveview => {
|
||||||
if let Some(fullstack_address) = fullstack_address {
|
if let Some(fullstack_address) = arguments.fullstack_address {
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
dx_src = ?TraceSrc::Dev,
|
dx_src = ?TraceSrc::Dev,
|
||||||
"Launching liveview server on http://{:?} 🎉",
|
"Launching liveview server on http://{:?} 🎉",
|
||||||
|
@ -191,7 +226,9 @@ impl BuildResult {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if arguments.serve {
|
||||||
tracing::info!(dx_src = ?TraceSrc::Dev, "Press [o] to open the app manually.");
|
tracing::info!(dx_src = ?TraceSrc::Dev, "Press [o] to open the app manually.");
|
||||||
|
}
|
||||||
|
|
||||||
let executable = self.executable.canonicalize()?;
|
let executable = self.executable.canonicalize()?;
|
||||||
let mut cmd = Command::new(executable);
|
let mut cmd = Command::new(executable);
|
||||||
|
@ -199,29 +236,36 @@ impl BuildResult {
|
||||||
// Set the env vars that the clients will expect
|
// Set the env vars that the clients will expect
|
||||||
// These need to be stable within a release version (ie 0.6.0)
|
// These need to be stable within a release version (ie 0.6.0)
|
||||||
cmd.env(dioxus_cli_config::CLI_ENABLED_ENV, "true");
|
cmd.env(dioxus_cli_config::CLI_ENABLED_ENV, "true");
|
||||||
if let Some(addr) = fullstack_address {
|
if let Some(addr) = arguments.fullstack_address {
|
||||||
cmd.env(dioxus_cli_config::SERVER_IP_ENV, addr.ip().to_string());
|
cmd.env(dioxus_cli_config::SERVER_IP_ENV, addr.ip().to_string());
|
||||||
cmd.env(dioxus_cli_config::SERVER_PORT_ENV, addr.port().to_string());
|
cmd.env(dioxus_cli_config::SERVER_PORT_ENV, addr.port().to_string());
|
||||||
}
|
}
|
||||||
|
if let Some(always_on_top) = arguments.always_on_top {
|
||||||
cmd.env(
|
cmd.env(
|
||||||
dioxus_cli_config::ALWAYS_ON_TOP_ENV,
|
dioxus_cli_config::ALWAYS_ON_TOP_ENV,
|
||||||
serve.always_on_top.unwrap_or(true).to_string(),
|
always_on_top.to_string(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
cmd.env(
|
cmd.env(
|
||||||
dioxus_cli_config::ASSET_ROOT_ENV,
|
dioxus_cli_config::ASSET_ROOT_ENV,
|
||||||
asset_root.display().to_string(),
|
arguments.asset_root.display().to_string(),
|
||||||
);
|
);
|
||||||
|
if let Some(devserver_addr) = arguments.devserver_addr {
|
||||||
cmd.env(
|
cmd.env(
|
||||||
dioxus_cli_config::DEVSERVER_RAW_ADDR_ENV,
|
dioxus_cli_config::DEVSERVER_RAW_ADDR_ENV,
|
||||||
devserver_addr.to_string(),
|
devserver_addr.to_string(),
|
||||||
);
|
);
|
||||||
cmd.env(dioxus_cli_config::APP_TITLE_ENV, app_title);
|
}
|
||||||
cmd.env(dioxus_cli_config::OUT_DIR, out_dir.display().to_string());
|
cmd.env(dioxus_cli_config::APP_TITLE_ENV, arguments.app_title);
|
||||||
|
cmd.env(
|
||||||
|
dioxus_cli_config::OUT_DIR,
|
||||||
|
arguments.out_dir.display().to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
cmd.stderr(Stdio::piped())
|
cmd.stderr(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.kill_on_drop(true)
|
.kill_on_drop(true)
|
||||||
.current_dir(workspace);
|
.current_dir(arguments.workspace);
|
||||||
|
|
||||||
Ok(Some(cmd.spawn()?))
|
Ok(Some(cmd.spawn()?))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::config::Platform;
|
use crate::{builder::OpenArguments, config::Platform};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -115,7 +115,20 @@ impl Build {
|
||||||
pub async fn build(&mut self, dioxus_crate: &mut DioxusCrate) -> Result<()> {
|
pub async fn build(&mut self, dioxus_crate: &mut DioxusCrate) -> Result<()> {
|
||||||
self.resolve(dioxus_crate)?;
|
self.resolve(dioxus_crate)?;
|
||||||
let build_requests = BuildRequest::create(false, dioxus_crate, self.clone())?;
|
let build_requests = BuildRequest::create(false, dioxus_crate, self.clone())?;
|
||||||
BuildRequest::build_all_parallel(build_requests).await?;
|
let builds = BuildRequest::build_all_parallel(build_requests).await?;
|
||||||
|
|
||||||
|
// If this is a static generation build, building involves running the server to generate static files
|
||||||
|
if self.platform.unwrap() == Platform::StaticGeneration {
|
||||||
|
println!("Building static site...");
|
||||||
|
for build in builds {
|
||||||
|
if let Some(mut result) =
|
||||||
|
build.open(OpenArguments::new_for_static_generation_build(dioxus_crate))?
|
||||||
|
{
|
||||||
|
result.wait().await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("Static site built!");
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use std::future::{poll_fn, Future, IntoFuture};
|
use std::future::{poll_fn, Future, IntoFuture};
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
|
|
||||||
|
use crate::builder::OpenArguments;
|
||||||
use crate::cli::serve::Serve;
|
use crate::cli::serve::Serve;
|
||||||
use crate::dioxus_crate::DioxusCrate;
|
use crate::dioxus_crate::DioxusCrate;
|
||||||
use crate::tracer::CLILogControl;
|
use crate::tracer::CLILogControl;
|
||||||
|
@ -156,23 +157,14 @@ pub async fn serve_all(
|
||||||
builder.children.clear();
|
builder.children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
let asset_dir = dioxus_crate
|
|
||||||
.dioxus_config
|
|
||||||
.application
|
|
||||||
.asset_dir
|
|
||||||
.canonicalize()
|
|
||||||
.unwrap_or(std::path::PathBuf::from("./assets"));
|
|
||||||
|
|
||||||
// If we have a build result, open it
|
// If we have a build result, open it
|
||||||
for build_result in results.iter() {
|
for build_result in results.iter() {
|
||||||
let child = build_result.open(
|
let child = build_result.open(
|
||||||
|
OpenArguments::new(
|
||||||
&serve.server_arguments,
|
&serve.server_arguments,
|
||||||
server.fullstack_address(),
|
server.fullstack_address(),
|
||||||
&dioxus_crate.workspace_dir(),
|
&dioxus_crate
|
||||||
&asset_dir,
|
)
|
||||||
server.ip,
|
|
||||||
dioxus_crate.dioxus_config.application.name.clone(),
|
|
||||||
dioxus_crate.out_dir()
|
|
||||||
);
|
);
|
||||||
match child {
|
match child {
|
||||||
Ok(Some(child_proc)) => builder.children.push((build_result.target_platform, child_proc)),
|
Ok(Some(child_proc)) => builder.children.push((build_result.target_platform, child_proc)),
|
||||||
|
@ -192,12 +184,12 @@ pub async fn serve_all(
|
||||||
server.send_reload_command().await;
|
server.send_reload_command().await;
|
||||||
},
|
},
|
||||||
|
|
||||||
// If the process exited *cleanly*, we can exit
|
// If the desktop process exited *cleanly*, we can exit
|
||||||
Ok(BuilderUpdate::ProcessExited { status, target_platform }) => {
|
Ok(BuilderUpdate::ProcessExited { status, target_platform }) => {
|
||||||
// Then remove the child process
|
// Then remove the child process
|
||||||
builder.children.retain(|(platform, _)| *platform != target_platform);
|
builder.children.retain(|(platform, _)| *platform != target_platform);
|
||||||
match status {
|
match (target_platform, status) {
|
||||||
Ok(status) => {
|
(TargetPlatform::Desktop, Ok(status)) => {
|
||||||
if status.success() {
|
if status.success() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -205,7 +197,9 @@ pub async fn serve_all(
|
||||||
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with status: {status}");
|
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with status: {status}");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
// Ignore the static generation platform exiting
|
||||||
|
(_ , Ok(_)) => {},
|
||||||
|
(_, Err(e)) => {
|
||||||
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with error: {e}");
|
tracing::error!(dx_src = ?TraceSrc::Dev, "Application exited with error: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl Server {
|
||||||
// If we're serving a fullstack app, we need to find a port to proxy to
|
// If we're serving a fullstack app, we need to find a port to proxy to
|
||||||
let fullstack_port = if matches!(
|
let fullstack_port = if matches!(
|
||||||
serve.build_arguments.platform(),
|
serve.build_arguments.platform(),
|
||||||
Platform::Liveview | Platform::Fullstack | Platform::StaticGeneration
|
Platform::Liveview | Platform::Fullstack
|
||||||
) {
|
) {
|
||||||
get_available_port(addr.ip())
|
get_available_port(addr.ip())
|
||||||
} else {
|
} else {
|
||||||
|
@ -368,7 +368,7 @@ fn setup_router(
|
||||||
|
|
||||||
// server the dir if it's web, otherwise let the fullstack server itself handle it
|
// server the dir if it's web, otherwise let the fullstack server itself handle it
|
||||||
match platform {
|
match platform {
|
||||||
Platform::Web => {
|
Platform::Web | Platform::StaticGeneration => {
|
||||||
// Route file service to output the .wasm and assets if this is a web build
|
// Route file service to output the .wasm and assets if this is a web build
|
||||||
let base_path = format!(
|
let base_path = format!(
|
||||||
"/{}",
|
"/{}",
|
||||||
|
@ -382,9 +382,9 @@ fn setup_router(
|
||||||
.trim_matches('/')
|
.trim_matches('/')
|
||||||
);
|
);
|
||||||
|
|
||||||
router = router.nest_service(&base_path, build_serve_dir(serve, config));
|
router = router.nest_service(&base_path, build_serve_dir(serve, config, platform));
|
||||||
}
|
}
|
||||||
Platform::Liveview | Platform::Fullstack | Platform::StaticGeneration => {
|
Platform::Liveview | Platform::Fullstack => {
|
||||||
// For fullstack and static generation, forward all requests to the server
|
// For fullstack and static generation, forward all requests to the server
|
||||||
let address = fullstack_address.unwrap();
|
let address = fullstack_address.unwrap();
|
||||||
|
|
||||||
|
@ -449,7 +449,11 @@ fn setup_router(
|
||||||
Ok(router)
|
Ok(router)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRouter {
|
fn build_serve_dir(
|
||||||
|
serve: &Serve,
|
||||||
|
cfg: &DioxusCrate,
|
||||||
|
platform: Platform,
|
||||||
|
) -> axum::routing::MethodRouter {
|
||||||
static CORS_UNSAFE: (HeaderValue, HeaderValue) = (
|
static CORS_UNSAFE: (HeaderValue, HeaderValue) = (
|
||||||
HeaderValue::from_static("unsafe-none"),
|
HeaderValue::from_static("unsafe-none"),
|
||||||
HeaderValue::from_static("unsafe-none"),
|
HeaderValue::from_static("unsafe-none"),
|
||||||
|
@ -465,7 +469,11 @@ fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRou
|
||||||
false => CORS_UNSAFE.clone(),
|
false => CORS_UNSAFE.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let out_dir = cfg.out_dir();
|
let out_dir = match platform {
|
||||||
|
// Static generation only serves files from the public directory
|
||||||
|
Platform::StaticGeneration => cfg.out_dir().join("public"),
|
||||||
|
_ => cfg.out_dir(),
|
||||||
|
};
|
||||||
let index_on_404 = cfg.dioxus_config.web.watcher.index_on_404;
|
let index_on_404 = cfg.dioxus_config.web.watcher.index_on_404;
|
||||||
|
|
||||||
get_service(
|
get_service(
|
||||||
|
@ -479,7 +487,7 @@ fn build_serve_dir(serve: &Serve, cfg: &DioxusCrate) -> axum::routing::MethodRou
|
||||||
let out_dir = out_dir.clone();
|
let out_dir = out_dir.clone();
|
||||||
move |response| async move { Ok(no_cache(index_on_404, &out_dir, response)) }
|
move |response| async move { Ok(no_cache(index_on_404, &out_dir, response)) }
|
||||||
})
|
})
|
||||||
.service(ServeDir::new(out_dir)),
|
.service(ServeDir::new(&out_dir)),
|
||||||
)
|
)
|
||||||
.handle_error(|error: Infallible| async move {
|
.handle_error(|error: Infallible| async move {
|
||||||
(
|
(
|
||||||
|
@ -500,7 +508,18 @@ fn no_cache(
|
||||||
// If there's a 404 and we're supposed to index on 404, upgrade that failed request to the index.html
|
// If there's a 404 and we're supposed to index on 404, upgrade that failed request to the index.html
|
||||||
// We might want to isnert a header here saying we *did* that but oh well
|
// We might want to isnert a header here saying we *did* that but oh well
|
||||||
if response.status() == StatusCode::NOT_FOUND && index_on_404 {
|
if response.status() == StatusCode::NOT_FOUND && index_on_404 {
|
||||||
let body = Body::from(std::fs::read_to_string(out_dir.join("index.html")).unwrap());
|
// First try to find a 404.html or 404/index.html file
|
||||||
|
let out_dir_404_html = out_dir.join("404.html");
|
||||||
|
let out_dir_404_index_html = out_dir.join("404").join("index.html");
|
||||||
|
let path = if out_dir_404_html.exists() {
|
||||||
|
out_dir_404_html
|
||||||
|
} else if out_dir_404_index_html.exists() {
|
||||||
|
out_dir_404_index_html
|
||||||
|
} else {
|
||||||
|
// If we can't find a 404.html or 404/index.html, just use the index.html
|
||||||
|
out_dir.join("index.html")
|
||||||
|
};
|
||||||
|
let body = Body::from(std::fs::read_to_string(path).unwrap());
|
||||||
|
|
||||||
response = Response::builder()
|
response = Response::builder()
|
||||||
.status(StatusCode::OK)
|
.status(StatusCode::OK)
|
||||||
|
|
8
packages/core/src/launch.rs
Normal file
8
packages/core/src/launch.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
//! This module contains utilities renderers use to integrate with the launch function.
|
||||||
|
|
||||||
|
/// A marker trait for platform configs. We use this marker to
|
||||||
|
/// make sure that the user doesn't accidentally pass in a config
|
||||||
|
/// builder instead of the config
|
||||||
|
pub trait LaunchConfig: 'static {}
|
||||||
|
|
||||||
|
impl LaunchConfig for () {}
|
|
@ -12,6 +12,7 @@ mod events;
|
||||||
mod fragment;
|
mod fragment;
|
||||||
mod generational_box;
|
mod generational_box;
|
||||||
mod global_context;
|
mod global_context;
|
||||||
|
mod launch;
|
||||||
mod mutations;
|
mod mutations;
|
||||||
mod nodes;
|
mod nodes;
|
||||||
mod properties;
|
mod properties;
|
||||||
|
@ -51,6 +52,7 @@ pub(crate) mod innerlude {
|
||||||
pub use crate::fragment::*;
|
pub use crate::fragment::*;
|
||||||
pub use crate::generational_box::*;
|
pub use crate::generational_box::*;
|
||||||
pub use crate::global_context::*;
|
pub use crate::global_context::*;
|
||||||
|
pub use crate::launch::*;
|
||||||
pub use crate::mutations::*;
|
pub use crate::mutations::*;
|
||||||
pub use crate::nodes::*;
|
pub use crate::nodes::*;
|
||||||
pub use crate::properties::*;
|
pub use crate::properties::*;
|
||||||
|
@ -75,10 +77,10 @@ pub(crate) mod innerlude {
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, generation, schedule_update, schedule_update_any, use_hook, vdom_is_rendering,
|
fc_to_builder, generation, schedule_update, schedule_update_any, use_hook, vdom_is_rendering,
|
||||||
AnyValue, Attribute, AttributeValue, CapturedError, Component, ComponentFunction, DynamicNode,
|
AnyValue, Attribute, AttributeValue, CapturedError, Component, ComponentFunction, DynamicNode,
|
||||||
Element, ElementId, Event, Fragment, HasAttributes, IntoDynNode, MarkerWrapper, Mutation,
|
Element, ElementId, Event, Fragment, HasAttributes, IntoDynNode, LaunchConfig, MarkerWrapper,
|
||||||
Mutations, NoOpMutations, Ok, Properties, Result, Runtime, ScopeId, ScopeState, SpawnIfAsync,
|
Mutation, Mutations, NoOpMutations, Ok, Properties, Result, Runtime, ScopeId, ScopeState,
|
||||||
Task, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner, VPlaceholder,
|
SpawnIfAsync, Task, Template, TemplateAttribute, TemplateNode, VComponent, VNode, VNodeInner,
|
||||||
VText, VirtualDom, WriteMutations,
|
VPlaceholder, VText, VirtualDom, WriteMutations,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many common types
|
/// The purpose of this module is to alleviate imports of many common types
|
||||||
|
|
|
@ -17,7 +17,7 @@ pub fn check_app_exits(app: fn() -> Element) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LaunchBuilder::desktop()
|
dioxus::LaunchBuilder::desktop()
|
||||||
.with_cfg(Config::new().with_window(WindowBuilder::new().with_visible(false)))
|
.with_cfg(Config::new().with_window(WindowBuilder::new().with_visible(false)))
|
||||||
.launch(app);
|
.launch(app);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use dioxus_core::LaunchConfig;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tao::window::{Icon, WindowBuilder};
|
use tao::window::{Icon, WindowBuilder};
|
||||||
|
@ -51,6 +52,8 @@ pub struct Config {
|
||||||
pub(crate) last_window_close_behavior: WindowCloseBehaviour,
|
pub(crate) last_window_close_behavior: WindowCloseBehaviour,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LaunchConfig for Config {}
|
||||||
|
|
||||||
pub(crate) type WryProtocol = (
|
pub(crate) type WryProtocol = (
|
||||||
String,
|
String,
|
||||||
Box<dyn Fn(HttpRequest<Vec<u8>>) -> HttpResponse<Cow<'static, [u8]>> + 'static>,
|
Box<dyn Fn(HttpRequest<Vec<u8>>) -> HttpResponse<Cow<'static, [u8]>> + 'static>,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
pub use crate::Config;
|
use crate::Config;
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
ipc::{IpcMethod, UserWindowEvent},
|
ipc::{IpcMethod, UserWindowEvent},
|
||||||
|
@ -82,8 +82,8 @@ pub fn launch_virtual_dom(virtual_dom: VirtualDom, desktop_config: Config) -> !
|
||||||
/// Launches the WebView and runs the event loop, with configuration and root props.
|
/// Launches the WebView and runs the event loop, with configuration and root props.
|
||||||
pub fn launch(
|
pub fn launch(
|
||||||
root: fn() -> Element,
|
root: fn() -> Element,
|
||||||
contexts: Vec<Box<dyn Fn() -> Box<dyn Any>>>,
|
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
|
||||||
platform_config: Config,
|
platform_config: Vec<Box<dyn Any>>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
let mut virtual_dom = VirtualDom::new(root);
|
let mut virtual_dom = VirtualDom::new(root);
|
||||||
|
|
||||||
|
@ -91,5 +91,10 @@ pub fn launch(
|
||||||
virtual_dom.insert_any_root_context(context());
|
virtual_dom.insert_any_root_context(context());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let platform_config = *platform_config
|
||||||
|
.into_iter()
|
||||||
|
.find_map(|cfg| cfg.downcast::<Config>().ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
launch_virtual_dom(virtual_dom, platform_config)
|
launch_virtual_dom(virtual_dom, platform_config)
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app() -> Element {
|
fn app() -> Element {
|
||||||
rsx!{
|
rsx! {
|
||||||
div {
|
div {
|
||||||
"hello world!"
|
"hello world!"
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ To launch an app, we use the `launch` method and use features in `Cargo.toml` to
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The #[component] attribute streamlines component creation.
|
// The #[component] attribute streamlines component creation.
|
||||||
|
@ -239,7 +239,7 @@ Using components, templates, and hooks, we can build a simple app.
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
|
|
@ -42,7 +42,7 @@ To launch an app, we use the `launch` method and use features in `Cargo.toml` to
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The #[component] attribute streamlines component creation.
|
// The #[component] attribute streamlines component creation.
|
||||||
|
@ -184,7 +184,7 @@ Using components, rsx, and hooks, we can build a simple app.
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
|
|
@ -2,20 +2,22 @@
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use dioxus_config_macro::*;
|
use dioxus_config_macro::*;
|
||||||
|
use dioxus_core::LaunchConfig;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
/// A builder for a fullstack app.
|
/// A builder for a fullstack app.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct LaunchBuilder<Cfg: 'static = (), ContextFn: ?Sized = ValidContext> {
|
pub struct LaunchBuilder {
|
||||||
launch_fn: LaunchFn<Cfg, ContextFn>,
|
launch_fn: LaunchFn,
|
||||||
contexts: Vec<Box<ContextFn>>,
|
contexts: Vec<ContextFn>,
|
||||||
|
configs: Vec<Box<dyn Any>>,
|
||||||
platform_config: Option<Cfg>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LaunchFn<Cfg, Context> = fn(fn() -> Element, Vec<Box<Context>>, Cfg);
|
pub type LaunchFn = fn(fn() -> Element, Vec<ContextFn>, Vec<Box<dyn Any>>);
|
||||||
|
/// A context function is a Send and Sync closure that returns a boxed trait object
|
||||||
|
pub type ContextFn = Box<dyn Fn() -> Box<dyn Any> + Send + Sync + 'static>;
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "fullstack",
|
feature = "fullstack",
|
||||||
|
@ -54,69 +56,74 @@ impl LaunchBuilder {
|
||||||
note = "No renderer is enabled. You must enable a renderer feature on the dioxus crate before calling the launch function.\nAdd `web`, `desktop`, `mobile`, `fullstack`, or `static-generation` to the `features` of dioxus field in your Cargo.toml.\n# Example\n```toml\n# ...\n[dependencies]\ndioxus = { version = \"0.5.0\", features = [\"web\"] }\n# ...\n```"
|
note = "No renderer is enabled. You must enable a renderer feature on the dioxus crate before calling the launch function.\nAdd `web`, `desktop`, `mobile`, `fullstack`, or `static-generation` to the `features` of dioxus field in your Cargo.toml.\n# Example\n```toml\n# ...\n[dependencies]\ndioxus = { version = \"0.5.0\", features = [\"web\"] }\n# ...\n```"
|
||||||
)
|
)
|
||||||
)]
|
)]
|
||||||
pub fn new() -> LaunchBuilder<current_platform::Config, ValidContext> {
|
pub fn new() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
|
// We can't use the `current_platform::launch` function directly because it may return ! or ()
|
||||||
launch_fn: |root, contexts, cfg| current_platform::launch(root, contexts, cfg),
|
launch_fn: |root, contexts, cfg| current_platform::launch(root, contexts, cfg),
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your web application.
|
/// Launch your web application.
|
||||||
#[cfg(feature = "web")]
|
#[cfg(feature = "web")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
||||||
pub fn web() -> LaunchBuilder<dioxus_web::Config, UnsendContext> {
|
pub fn web() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn: dioxus_web::launch::launch,
|
launch_fn: web_launch,
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your desktop application.
|
/// Launch your desktop application.
|
||||||
#[cfg(feature = "desktop")]
|
#[cfg(feature = "desktop")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
|
||||||
pub fn desktop() -> LaunchBuilder<dioxus_desktop::Config, UnsendContext> {
|
pub fn desktop() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn: |root, contexts, cfg| dioxus_desktop::launch::launch(root, contexts, cfg),
|
launch_fn: |root, contexts, cfg| dioxus_desktop::launch::launch(root, contexts, cfg),
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your fullstack application.
|
/// Launch your fullstack axum server.
|
||||||
#[cfg(feature = "fullstack")]
|
#[cfg(all(feature = "fullstack", feature = "server"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "fullstack")))]
|
#[cfg_attr(docsrs, doc(cfg(all(feature = "fullstack", feature = "server"))))]
|
||||||
pub fn fullstack() -> LaunchBuilder<dioxus_fullstack::Config, SendContext> {
|
pub fn server() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn: |root, contexts, cfg| dioxus_fullstack::launch::launch(root, contexts, cfg),
|
launch_fn: |root, contexts, cfg| {
|
||||||
|
dioxus_fullstack::server::launch::launch(root, contexts, cfg)
|
||||||
|
},
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your static site generation application.
|
/// Launch your static site generation application.
|
||||||
#[cfg(feature = "static-generation")]
|
#[cfg(all(feature = "static-generation", feature = "server"))]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "static-generation")))]
|
#[cfg_attr(
|
||||||
pub fn static_generation() -> LaunchBuilder<dioxus_static_site_generation::Config, SendContext>
|
docsrs,
|
||||||
{
|
doc(cfg(all(feature = "static-generation", feature = "server")))
|
||||||
|
)]
|
||||||
|
pub fn static_generation() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn: |root, contexts, cfg| {
|
launch_fn: |root, contexts, cfg| {
|
||||||
dioxus_static_site_generation::launch::launch(root, contexts, cfg)
|
dioxus_static_site_generation::launch::launch(root, contexts, cfg)
|
||||||
},
|
},
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launch your fullstack application.
|
/// Launch your fullstack application.
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
|
||||||
pub fn mobile() -> LaunchBuilder<dioxus_mobile::Config, UnsendContext> {
|
pub fn mobile() -> LaunchBuilder {
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn: |root, contexts, cfg| dioxus_mobile::launch::launch(root, contexts, cfg),
|
launch_fn: |root, contexts, cfg| dioxus_mobile::launch::launch(root, contexts, cfg),
|
||||||
contexts: Vec::new(),
|
contexts: Vec::new(),
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +139,7 @@ impl LaunchBuilder {
|
||||||
/// #[derive(Default)]
|
/// #[derive(Default)]
|
||||||
/// struct Config;
|
/// struct Config;
|
||||||
///
|
///
|
||||||
/// fn my_custom_launcher(root: fn() -> Element, contexts: Vec<Box<dyn Any>>, cfg: Config) {
|
/// fn my_custom_launcher(root: fn() -> Element, contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>, cfg: Vec<Box<dyn Any>>) {
|
||||||
/// println!("launching with root: {:?}", root());
|
/// println!("launching with root: {:?}", root());
|
||||||
/// loop {
|
/// loop {
|
||||||
/// println!("running...");
|
/// println!("running...");
|
||||||
|
@ -145,42 +152,24 @@ impl LaunchBuilder {
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// LaunchBuilder::custom(my_custom_launcher).launch(app);
|
/// dioxus::LaunchBuilder::custom(my_custom_launcher).launch(app);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn custom<Config, Context: ?Sized>(
|
pub fn custom(launch_fn: LaunchFn) -> LaunchBuilder {
|
||||||
launch_fn: LaunchFn<Config, Context>,
|
|
||||||
) -> LaunchBuilder<Config, Context> {
|
|
||||||
LaunchBuilder {
|
LaunchBuilder {
|
||||||
launch_fn,
|
launch_fn,
|
||||||
contexts: vec![],
|
contexts: vec![],
|
||||||
platform_config: None,
|
configs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fullstack platform builder
|
impl LaunchBuilder {
|
||||||
impl<Cfg> LaunchBuilder<Cfg, UnsendContext> {
|
|
||||||
/// Inject state into the root component's context that is created on the thread that the app is launched on.
|
|
||||||
pub fn with_context_provider(mut self, state: impl Fn() -> Box<dyn Any> + 'static) -> Self {
|
|
||||||
self.contexts.push(Box::new(state) as Box<UnsendContext>);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inject state into the root component's context.
|
|
||||||
pub fn with_context(mut self, state: impl Any + Clone + 'static) -> Self {
|
|
||||||
self.contexts
|
|
||||||
.push(Box::new(move || Box::new(state.clone())));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Cfg> LaunchBuilder<Cfg, SendContext> {
|
|
||||||
/// Inject state into the root component's context that is created on the thread that the app is launched on.
|
/// Inject state into the root component's context that is created on the thread that the app is launched on.
|
||||||
pub fn with_context_provider(
|
pub fn with_context_provider(
|
||||||
mut self,
|
mut self,
|
||||||
state: impl Fn() -> Box<dyn Any + Send + Sync> + Send + Sync + 'static,
|
state: impl Fn() -> Box<dyn Any> + Send + Sync + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.contexts.push(Box::new(state) as Box<SendContext>);
|
self.contexts.push(Box::new(state));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,38 +181,10 @@ impl<Cfg> LaunchBuilder<Cfg, SendContext> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait for converting a type into a platform-specific config:
|
impl LaunchBuilder {
|
||||||
/// - A unit value will be converted into `None`
|
|
||||||
/// - Any config will be converted into `Some(config)`
|
|
||||||
/// - If the config is for another platform, it will be converted into `None`
|
|
||||||
pub trait TryIntoConfig<Config = Self> {
|
|
||||||
fn into_config(self, config: &mut Option<Config>);
|
|
||||||
}
|
|
||||||
|
|
||||||
// A config can always be converted into itself
|
|
||||||
impl<Cfg> TryIntoConfig<Cfg> for Cfg {
|
|
||||||
fn into_config(self, config: &mut Option<Cfg>) {
|
|
||||||
*config = Some(self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The unit type can be converted into the current platform config.
|
|
||||||
// This makes it possible to use the `desktop!`, `web!`, etc macros with the launch API.
|
|
||||||
#[cfg(any(
|
|
||||||
feature = "liveview",
|
|
||||||
feature = "desktop",
|
|
||||||
feature = "mobile",
|
|
||||||
feature = "web",
|
|
||||||
feature = "fullstack"
|
|
||||||
))]
|
|
||||||
impl TryIntoConfig<current_platform::Config> for () {
|
|
||||||
fn into_config(self, config: &mut Option<current_platform::Config>) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
|
||||||
/// Provide a platform-specific config to the builder.
|
/// Provide a platform-specific config to the builder.
|
||||||
pub fn with_cfg(mut self, config: impl TryIntoConfig<Cfg>) -> Self {
|
pub fn with_cfg(mut self, config: impl LaunchConfig) -> Self {
|
||||||
config.into_config(&mut self.platform_config);
|
self.configs.push(Box::new(config));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +192,7 @@ impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
||||||
#[cfg(any(feature = "static-generation", feature = "web"))]
|
#[cfg(any(feature = "static-generation", feature = "web"))]
|
||||||
/// Launch your application.
|
/// Launch your application.
|
||||||
pub fn launch(self, app: fn() -> Element) {
|
pub fn launch(self, app: fn() -> Element) {
|
||||||
let cfg = self.platform_config.unwrap_or_default();
|
let cfg = self.configs;
|
||||||
|
|
||||||
(self.launch_fn)(app, self.contexts, cfg)
|
(self.launch_fn)(app, self.contexts, cfg)
|
||||||
}
|
}
|
||||||
|
@ -239,7 +200,7 @@ impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
||||||
#[cfg(not(any(feature = "static-generation", feature = "web")))]
|
#[cfg(not(any(feature = "static-generation", feature = "web")))]
|
||||||
/// Launch your application.
|
/// Launch your application.
|
||||||
pub fn launch(self, app: fn() -> Element) -> ! {
|
pub fn launch(self, app: fn() -> Element) -> ! {
|
||||||
let cfg = self.platform_config.unwrap_or_default();
|
let cfg = self.configs;
|
||||||
|
|
||||||
(self.launch_fn)(app, self.contexts, cfg);
|
(self.launch_fn)(app, self.contexts, cfg);
|
||||||
unreachable!("Launching an application will never exit")
|
unreachable!("Launching an application will never exit")
|
||||||
|
@ -256,147 +217,67 @@ impl<Cfg: Default + 'static, ContextFn: ?Sized> LaunchBuilder<Cfg, ContextFn> {
|
||||||
/// - `web`
|
/// - `web`
|
||||||
/// - `liveview`
|
/// - `liveview`
|
||||||
mod current_platform {
|
mod current_platform {
|
||||||
macro_rules! if_else_cfg {
|
#[cfg(all(feature = "fullstack", feature = "server"))]
|
||||||
(if $attr:meta { $($then:item)* } else { $($else:item)* }) => {
|
pub use dioxus_fullstack::server::launch::*;
|
||||||
$(
|
|
||||||
#[cfg($attr)]
|
|
||||||
$then
|
|
||||||
)*
|
|
||||||
$(
|
|
||||||
#[cfg(not($attr))]
|
|
||||||
$else
|
|
||||||
)*
|
|
||||||
};
|
|
||||||
}
|
|
||||||
use crate::prelude::TryIntoConfig;
|
|
||||||
|
|
||||||
#[cfg(feature = "fullstack")]
|
#[cfg(all(
|
||||||
pub use dioxus_fullstack::launch::*;
|
feature = "desktop",
|
||||||
|
not(all(feature = "fullstack", feature = "server"))
|
||||||
#[cfg(all(feature = "fullstack", feature = "axum"))]
|
))]
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config>
|
|
||||||
for ::dioxus_fullstack::prelude::ServeConfigBuilder
|
|
||||||
{
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {
|
|
||||||
match config {
|
|
||||||
Some(config) => config.set_server_config(self),
|
|
||||||
None => {
|
|
||||||
*config = Some(
|
|
||||||
crate::launch::current_platform::Config::new().with_server_config(self),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(feature = "desktop", feature = "mobile"))]
|
|
||||||
if_else_cfg! {
|
|
||||||
if not(feature = "fullstack") {
|
|
||||||
#[cfg(feature = "desktop")]
|
|
||||||
pub use dioxus_desktop::launch::*;
|
pub use dioxus_desktop::launch::*;
|
||||||
#[cfg(not(feature = "desktop"))]
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "mobile",
|
||||||
|
not(feature = "desktop"),
|
||||||
|
not(all(feature = "fullstack", feature = "server"))
|
||||||
|
))]
|
||||||
pub use dioxus_mobile::launch::*;
|
pub use dioxus_mobile::launch::*;
|
||||||
} else {
|
|
||||||
if_else_cfg! {
|
|
||||||
if feature = "desktop" {
|
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_desktop::Config {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {
|
|
||||||
match config {
|
|
||||||
Some(config) => config.set_desktop_config(self),
|
|
||||||
None => *config = Some(crate::launch::current_platform::Config::new().with_desktop_config(self)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_mobile::Config {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {
|
|
||||||
match config {
|
|
||||||
Some(config) => config.set_mobile_cfg(self),
|
|
||||||
None => *config = Some(crate::launch::current_platform::Config::new().with_mobile_cfg(self)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "static-generation")]
|
#[cfg(all(
|
||||||
if_else_cfg! {
|
all(feature = "static-generation", feature = "server"),
|
||||||
if all(not(feature = "fullstack"), not(feature = "desktop"), not(feature = "mobile")) {
|
not(all(feature = "fullstack", feature = "server")),
|
||||||
|
not(feature = "desktop"),
|
||||||
|
not(feature = "mobile")
|
||||||
|
))]
|
||||||
pub use dioxus_static_site_generation::launch::*;
|
pub use dioxus_static_site_generation::launch::*;
|
||||||
} else {
|
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_static_site_generation::Config {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "web")]
|
#[cfg(all(
|
||||||
if_else_cfg! {
|
|
||||||
if not(any(feature = "desktop", feature = "mobile", feature = "fullstack", feature = "static-generation")) {
|
|
||||||
pub use dioxus_web::launch::*;
|
|
||||||
} else {
|
|
||||||
if_else_cfg! {
|
|
||||||
if feature = "fullstack" {
|
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_web::Config {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {
|
|
||||||
match config {
|
|
||||||
Some(config) => config.set_web_config(self),
|
|
||||||
None => *config = Some(crate::launch::current_platform::Config::new().with_web_config(self)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
impl TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_web::Config {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "liveview")]
|
|
||||||
if_else_cfg! {
|
|
||||||
if
|
|
||||||
not(any(
|
|
||||||
feature = "web",
|
feature = "web",
|
||||||
feature = "desktop",
|
not(all(feature = "fullstack", feature = "server")),
|
||||||
feature = "mobile",
|
not(all(feature = "static-generation", feature = "server")),
|
||||||
feature = "fullstack",
|
not(feature = "desktop"),
|
||||||
feature = "static-generation"
|
not(feature = "mobile"),
|
||||||
))
|
))]
|
||||||
{
|
pub fn launch(
|
||||||
|
root: fn() -> dioxus_core::Element,
|
||||||
|
contexts: Vec<super::ContextFn>,
|
||||||
|
platform_config: Vec<Box<dyn std::any::Any>>,
|
||||||
|
) {
|
||||||
|
super::web_launch(root, contexts, platform_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(
|
||||||
|
feature = "liveview",
|
||||||
|
not(all(feature = "fullstack", feature = "server")),
|
||||||
|
not(all(feature = "static-generation", feature = "server")),
|
||||||
|
not(feature = "desktop"),
|
||||||
|
not(feature = "mobile"),
|
||||||
|
not(feature = "web"),
|
||||||
|
))]
|
||||||
pub use dioxus_liveview::launch::*;
|
pub use dioxus_liveview::launch::*;
|
||||||
} else {
|
|
||||||
impl<R: ::dioxus_liveview::LiveviewRouter> TryIntoConfig<crate::launch::current_platform::Config> for ::dioxus_liveview::Config<R> {
|
|
||||||
fn into_config(self, config: &mut Option<crate::launch::current_platform::Config>) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(
|
||||||
feature = "liveview",
|
feature = "liveview",
|
||||||
|
all(feature = "fullstack", feature = "server"),
|
||||||
|
all(feature = "static-generation", feature = "server"),
|
||||||
feature = "desktop",
|
feature = "desktop",
|
||||||
feature = "mobile",
|
feature = "mobile",
|
||||||
feature = "web",
|
feature = "web",
|
||||||
feature = "fullstack",
|
|
||||||
feature = "static-generation"
|
|
||||||
)))]
|
|
||||||
pub type Config = ();
|
|
||||||
|
|
||||||
#[cfg(not(any(
|
|
||||||
feature = "liveview",
|
|
||||||
feature = "desktop",
|
|
||||||
feature = "mobile",
|
|
||||||
feature = "web",
|
|
||||||
feature = "fullstack",
|
|
||||||
feature = "static-generation"
|
|
||||||
)))]
|
)))]
|
||||||
pub fn launch(
|
pub fn launch(
|
||||||
root: fn() -> dioxus_core::Element,
|
root: fn() -> dioxus_core::Element,
|
||||||
contexts: Vec<Box<super::ValidContext>>,
|
contexts: Vec<super::ContextFn>,
|
||||||
platform_config: (),
|
platform_config: Vec<Box<dyn std::any::Any>>,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
#[cfg(feature = "third-party-renderer")]
|
#[cfg(feature = "third-party-renderer")]
|
||||||
panic!("No first party renderer feature enabled. It looks like you are trying to use a third party renderer. You will need to use the launch function from the third party renderer crate.");
|
panic!("No first party renderer feature enabled. It looks like you are trying to use a third party renderer. You will need to use the launch function from the third party renderer crate.");
|
||||||
|
@ -409,22 +290,6 @@ mod current_platform {
|
||||||
macro_rules! impl_launch {
|
macro_rules! impl_launch {
|
||||||
($($return_type:tt),*) => {
|
($($return_type:tt),*) => {
|
||||||
/// Launch your application without any additional configuration. See [`LaunchBuilder`] for more options.
|
/// Launch your application without any additional configuration. See [`LaunchBuilder`] for more options.
|
||||||
// If you aren't using a third party renderer and this is not a docs.rs build, generate a warning about no renderer being enabled
|
|
||||||
#[cfg_attr(
|
|
||||||
all(not(any(
|
|
||||||
docsrs,
|
|
||||||
feature = "third-party-renderer",
|
|
||||||
feature = "liveview",
|
|
||||||
feature = "desktop",
|
|
||||||
feature = "mobile",
|
|
||||||
feature = "web",
|
|
||||||
feature = "fullstack",
|
|
||||||
feature = "static-generation"
|
|
||||||
))),
|
|
||||||
deprecated(
|
|
||||||
note = "No renderer is enabled. You must enable a renderer feature on the dioxus crate before calling the launch function.\nAdd `web`, `desktop`, `mobile`, `fullstack`, or `static-generation` to the `features` of dioxus field in your Cargo.toml.\n# Example\n```toml\n# ...\n[dependencies]\ndioxus = { version = \"0.5.0\", features = [\"web\"] }\n# ...\n```"
|
|
||||||
)
|
|
||||||
)]
|
|
||||||
pub fn launch(app: fn() -> Element) -> $($return_type)* {
|
pub fn launch(app: fn() -> Element) -> $($return_type)* {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
LaunchBuilder::new().launch(app)
|
LaunchBuilder::new().launch(app)
|
||||||
|
@ -439,29 +304,40 @@ impl_launch!(());
|
||||||
impl_launch!(!);
|
impl_launch!(!);
|
||||||
|
|
||||||
#[cfg(feature = "web")]
|
#[cfg(feature = "web")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
fn web_launch(
|
||||||
/// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
|
root: fn() -> dioxus_core::Element,
|
||||||
pub fn launch_web(app: fn() -> Element) {
|
contexts: Vec<super::ContextFn>,
|
||||||
LaunchBuilder::web().launch(app)
|
platform_config: Vec<Box<dyn std::any::Any>>,
|
||||||
}
|
) {
|
||||||
|
// If the server feature is enabled, launch the client with hydration enabled
|
||||||
|
#[cfg(any(feature = "static-generation", feature = "fullstack"))]
|
||||||
|
{
|
||||||
|
let platform_config = platform_config
|
||||||
|
.into_iter()
|
||||||
|
.find_map(|cfg| cfg.downcast::<dioxus_web::Config>().ok())
|
||||||
|
.unwrap_or_default()
|
||||||
|
.hydrate(true);
|
||||||
|
|
||||||
#[cfg(feature = "desktop")]
|
let factory = move || {
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
|
let mut vdom = dioxus_core::VirtualDom::new(root);
|
||||||
/// Launch your desktop application without any additional configuration. See [`LaunchBuilder`] for more options.
|
for context in contexts {
|
||||||
pub fn launch_desktop(app: fn() -> Element) {
|
vdom.insert_any_root_context(context());
|
||||||
LaunchBuilder::desktop().launch(app)
|
}
|
||||||
}
|
#[cfg(feature = "document")]
|
||||||
|
{
|
||||||
|
#[cfg(feature = "fullstack")]
|
||||||
|
use dioxus_fullstack::document;
|
||||||
|
#[cfg(all(feature = "static-generation", not(feature = "fullstack")))]
|
||||||
|
use dioxus_static_site_generation::document;
|
||||||
|
let document = std::rc::Rc::new(document::web::FullstackWebDocument)
|
||||||
|
as std::rc::Rc<dyn crate::prelude::Document>;
|
||||||
|
vdom.provide_root_context(document);
|
||||||
|
}
|
||||||
|
vdom
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "fullstack")]
|
dioxus_web::launch::launch_virtual_dom(factory(), platform_config)
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "fullstack")))]
|
}
|
||||||
/// Launch your fullstack application without any additional configuration. See [`LaunchBuilder`] for more options.
|
#[cfg(not(any(feature = "static-generation", feature = "fullstack")))]
|
||||||
pub fn launch_fullstack(app: fn() -> Element) {
|
dioxus_web::launch::launch(root, contexts, platform_config);
|
||||||
LaunchBuilder::fullstack().launch(app)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "mobile")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
|
|
||||||
/// Launch your mobile application without any additional configuration. See [`LaunchBuilder`] for more options.
|
|
||||||
pub fn launch_mobile(app: fn() -> Element) {
|
|
||||||
LaunchBuilder::mobile().launch(app)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,7 @@ mod launch;
|
||||||
|
|
||||||
#[cfg(feature = "launch")]
|
#[cfg(feature = "launch")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "launch")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "launch")))]
|
||||||
#[allow(deprecated)]
|
pub use crate::launch::*;
|
||||||
pub use launch::launch;
|
|
||||||
|
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "hooks")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "hooks")))]
|
||||||
|
@ -60,9 +59,6 @@ pub use dioxus_html as html;
|
||||||
pub use dioxus_core_macro as core_macro;
|
pub use dioxus_core_macro as core_macro;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
#[cfg(feature = "launch")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "launch")))]
|
|
||||||
pub use crate::launch::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "hooks")]
|
#[cfg(feature = "hooks")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "hooks")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "hooks")))]
|
||||||
|
|
|
@ -37,7 +37,77 @@ Full stack Dioxus in under 30 lines of code
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn App() -> Element {
|
||||||
|
let mut meaning = use_signal(|| None);
|
||||||
|
|
||||||
|
rsx! {
|
||||||
|
h1 { "Meaning of life: {meaning:?}" }
|
||||||
|
button {
|
||||||
|
onclick: move |_| async move {
|
||||||
|
if let Ok(data) = get_meaning("life the universe and everything".into()).await {
|
||||||
|
meaning.set(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Run a server function"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[server]
|
||||||
|
async fn get_meaning(of: String) -> Result<Option<u32>, ServerFnError> {
|
||||||
|
Ok(of.contains("life").then(|| 42))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Axum Integration
|
||||||
|
|
||||||
|
If you have an existing Axum router or you need more control over the server, you can use the [`DioxusRouterExt`](https://docs.rs/dioxus-fullstack/0.6.0-alpha.2/dioxus_fullstack/prelude/trait.DioxusRouterExt.html) trait to integrate with your existing Axum router.
|
||||||
|
|
||||||
|
First, make sure your `axum` dependency is optional and enabled by the server feature flag. Axum cannot be compiled to wasm, so if it is enabled by default, it will cause a compile error:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
dioxus = { version = "*", features = ["fullstack"] }
|
||||||
|
axum = { version = "0.7.0", optional = true }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
server = ["dep:axum", "dioxus/server"]
|
||||||
|
web = ["dioxus/web"]
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we can set up dioxus with the axum server:
|
||||||
|
|
||||||
|
```rust, no_run
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
// The entry point for the server
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
fn main() {
|
||||||
|
// Get the address the server should run on. If the CLI is running, the CLI proxies fullstack into the main address
|
||||||
|
// and we use the generated address the CLI gives us
|
||||||
|
let address = dioxus_cli_config::RuntimeCLIArguments::fullstack_address_or_localhost();
|
||||||
|
|
||||||
|
// Set up the axum router
|
||||||
|
let router = axum::Router::new()
|
||||||
|
// You can add a dioxus application to the router with the `serve_dioxus_application` method
|
||||||
|
// This will add a fallback route to the router that will serve your component and server functions
|
||||||
|
.serve_dioxus_application(ServeConfigBuilder::default(), App);
|
||||||
|
|
||||||
|
// Finally, we can launch the server
|
||||||
|
let router = router.into_make_service();
|
||||||
|
let listener = tokio::net::TcpListener::bind(address).await.unwrap();
|
||||||
|
axum::serve(listener, router).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For any other platform, we just launch the app
|
||||||
|
#[cfg(not(feature = "server"))]
|
||||||
|
fn main() {
|
||||||
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -111,7 +181,7 @@ fn main() {
|
||||||
// For any other platform, we just launch the app
|
// For any other platform, we just launch the app
|
||||||
#[cfg(not(feature = "server"))]
|
#[cfg(not(feature = "server"))]
|
||||||
fn main() {
|
fn main() {
|
||||||
launch(App);
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
|
|
@ -1,289 +0,0 @@
|
||||||
//! Launch helper macros for fullstack apps
|
|
||||||
#![allow(unused)]
|
|
||||||
use crate::prelude::*;
|
|
||||||
use dioxus_lib::prelude::*;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
/// Settings for a fullstack app.
|
|
||||||
///
|
|
||||||
/// Depending on what features are enabled, you can pass in configurations for each client platform as well as the server:
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the server config if the server feature is enabled
|
|
||||||
/// server_only! {
|
|
||||||
/// cfg = cfg.with_server_config(ServeConfigBuilder::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Only set the web config if the web feature is enabled
|
|
||||||
/// web! {
|
|
||||||
/// cfg = cfg.with_web_config(dioxus::web::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Only set the desktop config if the desktop feature is enabled
|
|
||||||
/// desktop! {
|
|
||||||
/// cfg = cfg.with_desktop_config(dioxus::desktop::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
pub struct Config {
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
pub(crate) server_cfg: ServeConfigBuilder,
|
|
||||||
|
|
||||||
#[cfg(feature = "web")]
|
|
||||||
pub(crate) web_cfg: dioxus_web::Config,
|
|
||||||
|
|
||||||
#[cfg(feature = "desktop")]
|
|
||||||
pub(crate) desktop_cfg: dioxus_desktop::Config,
|
|
||||||
|
|
||||||
#[cfg(feature = "mobile")]
|
|
||||||
pub(crate) mobile_cfg: dioxus_mobile::Config,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::derivable_impls)]
|
|
||||||
impl Default for Config {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
server_cfg: ServeConfigBuilder::new(),
|
|
||||||
#[cfg(feature = "web")]
|
|
||||||
web_cfg: dioxus_web::Config::default(),
|
|
||||||
#[cfg(feature = "desktop")]
|
|
||||||
desktop_cfg: dioxus_desktop::Config::default(),
|
|
||||||
#[cfg(feature = "mobile")]
|
|
||||||
mobile_cfg: dioxus_mobile::Config::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
/// Create a new config for a fullstack app.
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the incremental renderer config. The incremental config can be used to improve
|
|
||||||
/// performance of heavy routes by caching the rendered html in memory and/or the file system.
|
|
||||||
///
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the server config if the server feature is enabled
|
|
||||||
/// server_only! {
|
|
||||||
/// cfg = cfg.incremental(IncrementalRendererConfig::default().with_memory_cache_limit(10000));
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
|
|
||||||
pub fn incremental(self, cfg: IncrementalRendererConfig) -> Self {
|
|
||||||
Self {
|
|
||||||
server_cfg: self.server_cfg.incremental(cfg),
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the server config
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the server config if the server feature is enabled
|
|
||||||
/// server_only! {
|
|
||||||
/// cfg = cfg.with_server_config(ServeConfigBuilder::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
|
|
||||||
pub fn with_server_config(self, server_cfg: ServeConfigBuilder) -> Self {
|
|
||||||
Self { server_cfg, ..self }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the server config by modifying the config in place
|
|
||||||
///
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the server config if the server feature is enabled
|
|
||||||
/// server_only! {
|
|
||||||
/// cfg.set_server_config(ServeConfigBuilder::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
|
|
||||||
pub fn set_server_config(&mut self, server_cfg: ServeConfigBuilder) {
|
|
||||||
self.server_cfg = server_cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the web config
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the web config if the server feature is enabled
|
|
||||||
/// web! {
|
|
||||||
/// cfg = cfg.with_web_config(dioxus::web::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "web")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
|
||||||
pub fn with_web_config(self, web_cfg: dioxus_web::Config) -> Self {
|
|
||||||
Self { web_cfg, ..self }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the server config by modifying the config in place
|
|
||||||
///
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the web config if the server feature is enabled
|
|
||||||
/// web! {
|
|
||||||
/// cfg.set_web_config(dioxus::web::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "web")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "web")))]
|
|
||||||
pub fn set_web_config(&mut self, web_cfg: dioxus_web::Config) {
|
|
||||||
self.web_cfg = web_cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the desktop config
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the desktop config if the server feature is enabled
|
|
||||||
/// desktop! {
|
|
||||||
/// cfg = cfg.with_desktop_config(dioxus::desktop::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "desktop")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
|
|
||||||
pub fn with_desktop_config(self, desktop_cfg: dioxus_desktop::Config) -> Self {
|
|
||||||
Self {
|
|
||||||
desktop_cfg,
|
|
||||||
..self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the desktop config by modifying the config in place
|
|
||||||
///
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the desktop config if the server feature is enabled
|
|
||||||
/// desktop! {
|
|
||||||
/// cfg.set_desktop_config(dioxus::desktop::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// ```
|
|
||||||
#[cfg(feature = "desktop")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "desktop")))]
|
|
||||||
pub fn set_desktop_config(&mut self, desktop_cfg: dioxus_desktop::Config) {
|
|
||||||
self.desktop_cfg = desktop_cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the mobile config
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the mobile config if the server feature is enabled
|
|
||||||
/// mobile! {
|
|
||||||
/// cfg = cfg.with_mobile_cfg(dioxus::mobile::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// Set the mobile config.
|
|
||||||
#[cfg(feature = "mobile")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
|
|
||||||
pub fn with_mobile_cfg(self, mobile_cfg: dioxus_mobile::Config) -> Self {
|
|
||||||
Self { mobile_cfg, ..self }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the mobile config by modifying the config in place
|
|
||||||
/// ```rust, no_run
|
|
||||||
/// # fn app() -> Element { todo!() }
|
|
||||||
/// use dioxus::prelude::*;
|
|
||||||
///
|
|
||||||
/// let mut cfg = dioxus::fullstack::Config::new();
|
|
||||||
///
|
|
||||||
/// // Only set the mobile config if the server feature is enabled
|
|
||||||
/// mobile! {
|
|
||||||
/// cfg.set_mobile_cfg(dioxus::mobile::Config::default());
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// // Finally, launch the app with the config
|
|
||||||
/// LaunchBuilder::new()
|
|
||||||
/// .with_cfg(cfg)
|
|
||||||
/// .launch(app);
|
|
||||||
/// Set the mobile config.
|
|
||||||
#[cfg(feature = "mobile")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
|
|
||||||
pub fn set_mobile_cfg(&mut self, mobile_cfg: dioxus_mobile::Config) {
|
|
||||||
self.mobile_cfg = mobile_cfg;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,8 @@
|
||||||
//! This module contains the document providers for the fullstack platform.
|
//! This module contains the document providers for the fullstack platform.
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
pub(crate) mod server;
|
pub mod server;
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
pub use server::ServerDocument;
|
pub use server::ServerDocument;
|
||||||
#[cfg(all(feature = "web", feature = "document"))]
|
#[cfg(all(feature = "web", feature = "document"))]
|
||||||
pub(crate) mod web;
|
pub mod web;
|
||||||
|
|
|
@ -11,7 +11,8 @@ fn head_element_written_on_server() -> bool {
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct FullstackWebDocument;
|
/// A document provider for fullstack web clients
|
||||||
|
pub struct FullstackWebDocument;
|
||||||
|
|
||||||
impl Document for FullstackWebDocument {
|
impl Document for FullstackWebDocument {
|
||||||
fn new_evaluator(
|
fn new_evaluator(
|
||||||
|
|
|
@ -1,171 +0,0 @@
|
||||||
//! This module contains the `launch` function, which is the main entry point for dioxus fullstack
|
|
||||||
|
|
||||||
use std::{any::Any, sync::Arc};
|
|
||||||
|
|
||||||
use dioxus_lib::prelude::{Element, VirtualDom};
|
|
||||||
|
|
||||||
pub use crate::Config;
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub(crate) type ContextProviders = Arc<
|
|
||||||
Vec<Box<dyn Fn() -> Box<dyn std::any::Any + Send + Sync + 'static> + Send + Sync + 'static>>,
|
|
||||||
>;
|
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
fn virtual_dom_factory(
|
|
||||||
root: fn() -> Element,
|
|
||||||
contexts: ContextProviders,
|
|
||||||
) -> impl Fn() -> VirtualDom + 'static {
|
|
||||||
move || {
|
|
||||||
let mut vdom = VirtualDom::new(root);
|
|
||||||
for context in &*contexts {
|
|
||||||
vdom.insert_any_root_context(context());
|
|
||||||
}
|
|
||||||
vdom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
/// Launch a fullstack app with the given root component, contexts, and config.
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn launch(
|
|
||||||
root: fn() -> Element,
|
|
||||||
contexts: Vec<Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>>,
|
|
||||||
platform_config: Config,
|
|
||||||
) -> ! {
|
|
||||||
let contexts = Arc::new(contexts);
|
|
||||||
let factory = virtual_dom_factory(root, contexts.clone());
|
|
||||||
#[cfg(all(feature = "server", not(target_arch = "wasm32")))]
|
|
||||||
tokio::runtime::Runtime::new()
|
|
||||||
.unwrap()
|
|
||||||
.block_on(async move {
|
|
||||||
launch_server(platform_config, factory, contexts).await;
|
|
||||||
});
|
|
||||||
|
|
||||||
unreachable!("Launching a fullstack app should never return")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(not(feature = "server"), feature = "web"))]
|
|
||||||
/// Launch a fullstack app with the given root component, contexts, and config.
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn launch(
|
|
||||||
root: fn() -> Element,
|
|
||||||
#[allow(unused_mut)] mut contexts: Vec<
|
|
||||||
Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>,
|
|
||||||
>,
|
|
||||||
platform_config: Config,
|
|
||||||
) {
|
|
||||||
let contexts = Arc::new(contexts);
|
|
||||||
let mut factory = virtual_dom_factory(root, contexts);
|
|
||||||
let cfg = platform_config.web_cfg.hydrate(true);
|
|
||||||
|
|
||||||
#[cfg(feature = "document")]
|
|
||||||
let factory = move || {
|
|
||||||
let mut vdom = factory();
|
|
||||||
let document = std::rc::Rc::new(crate::document::web::FullstackWebDocument)
|
|
||||||
as std::rc::Rc<dyn dioxus_lib::prelude::document::Document>;
|
|
||||||
vdom.provide_root_context(document);
|
|
||||||
vdom
|
|
||||||
};
|
|
||||||
|
|
||||||
dioxus_web::launch::launch_virtual_dom(factory(), cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(not(any(feature = "server", feature = "web")), feature = "desktop"))]
|
|
||||||
/// Launch a fullstack app with the given root component, contexts, and config.
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn launch(
|
|
||||||
root: fn() -> Element,
|
|
||||||
contexts: Vec<Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>>,
|
|
||||||
platform_config: Config,
|
|
||||||
) -> ! {
|
|
||||||
let contexts = Arc::new(contexts);
|
|
||||||
let factory = virtual_dom_factory(root, contexts);
|
|
||||||
let cfg = platform_config.desktop_cfg;
|
|
||||||
dioxus_desktop::launch::launch_virtual_dom(factory(), cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(all(
|
|
||||||
not(any(feature = "server", feature = "web", feature = "desktop")),
|
|
||||||
feature = "mobile"
|
|
||||||
))]
|
|
||||||
/// Launch a fullstack app with the given root component, contexts, and config.
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn launch(
|
|
||||||
root: fn() -> Element,
|
|
||||||
contexts: Vec<Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>>,
|
|
||||||
platform_config: Config,
|
|
||||||
) -> ! {
|
|
||||||
let contexts = Arc::new(contexts);
|
|
||||||
let factory = virtual_dom_factory(root, contexts.clone());
|
|
||||||
let cfg = platform_config.mobile_cfg;
|
|
||||||
dioxus_mobile::launch::launch_virtual_dom(factory(), cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(
|
|
||||||
feature = "server",
|
|
||||||
feature = "web",
|
|
||||||
feature = "desktop",
|
|
||||||
feature = "mobile"
|
|
||||||
)))]
|
|
||||||
/// Launch a fullstack app with the given root component, contexts, and config.
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn launch(
|
|
||||||
root: fn() -> Element,
|
|
||||||
contexts: Vec<Box<dyn Fn() -> Box<dyn Any + Send + Sync> + Send + Sync>>,
|
|
||||||
platform_config: Config,
|
|
||||||
) -> ! {
|
|
||||||
panic!("No platform feature enabled. Please enable one of the following features: axum, desktop, or web to use the launch API.")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
#[allow(unused)]
|
|
||||||
/// Launch a server application
|
|
||||||
async fn launch_server(
|
|
||||||
platform_config: Config,
|
|
||||||
build_virtual_dom: impl Fn() -> VirtualDom + Send + Sync + 'static,
|
|
||||||
context_providers: ContextProviders,
|
|
||||||
) {
|
|
||||||
// Get the address the server should run on. If the CLI is running, the CLI proxies fullstack into the main address
|
|
||||||
// and we use the generated address the CLI gives us
|
|
||||||
let address = dioxus_cli_config::fullstack_address_or_localhost();
|
|
||||||
|
|
||||||
#[cfg(feature = "axum")]
|
|
||||||
{
|
|
||||||
use crate::axum_adapter::DioxusRouterExt;
|
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
let mut router =
|
|
||||||
axum::Router::new().register_server_functions_with_context(context_providers);
|
|
||||||
|
|
||||||
#[cfg(not(any(feature = "desktop", feature = "mobile")))]
|
|
||||||
{
|
|
||||||
use crate::prelude::RenderHandleState;
|
|
||||||
use crate::prelude::SSRState;
|
|
||||||
|
|
||||||
match platform_config.server_cfg.build() {
|
|
||||||
Ok(cfg) => {
|
|
||||||
router = router.serve_static_assets();
|
|
||||||
|
|
||||||
router = router.fallback(
|
|
||||||
axum::routing::get(crate::axum_adapter::render_handler).with_state(
|
|
||||||
RenderHandleState::new_with_virtual_dom_factory(cfg, build_virtual_dom),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
tracing::trace!("Failed to create render handler. This is expected if you are only using fullstack for desktop/mobile server functions: {}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let router = router.into_make_service();
|
|
||||||
let listener = tokio::net::TcpListener::bind(address).await.unwrap();
|
|
||||||
|
|
||||||
axum::serve(listener, router).await.unwrap();
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "axum"))]
|
|
||||||
{
|
|
||||||
panic!("Launching with dioxus fullstack requires the axum feature. If you are using a community fullstack adapter, please check the documentation for that adapter to see how to launch the application.");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -10,13 +10,9 @@ mod html_storage;
|
||||||
|
|
||||||
#[cfg(feature = "axum")]
|
#[cfg(feature = "axum")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
|
||||||
mod axum_adapter;
|
pub mod server;
|
||||||
|
|
||||||
mod config;
|
|
||||||
mod hooks;
|
mod hooks;
|
||||||
pub mod launch;
|
|
||||||
|
|
||||||
pub use config::*;
|
|
||||||
|
|
||||||
pub mod document;
|
pub mod document;
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
|
@ -39,7 +35,7 @@ pub mod prelude {
|
||||||
|
|
||||||
#[cfg(feature = "axum")]
|
#[cfg(feature = "axum")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
|
||||||
pub use crate::axum_adapter::*;
|
pub use crate::server::*;
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
#[cfg(feature = "server")]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "server")))]
|
||||||
|
|
|
@ -5,6 +5,8 @@ use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use dioxus_lib::prelude::dioxus_core::LaunchConfig;
|
||||||
|
|
||||||
/// A ServeConfig is used to configure how to serve a Dioxus application. It contains information about how to serve static assets, and what content to render with [`dioxus-ssr`].
|
/// A ServeConfig is used to configure how to serve a Dioxus application. It contains information about how to serve static assets, and what content to render with [`dioxus-ssr`].
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct ServeConfigBuilder {
|
pub struct ServeConfigBuilder {
|
||||||
|
@ -14,6 +16,8 @@ pub struct ServeConfigBuilder {
|
||||||
pub(crate) incremental: Option<dioxus_isrg::IncrementalRendererConfig>,
|
pub(crate) incremental: Option<dioxus_isrg::IncrementalRendererConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LaunchConfig for ServeConfigBuilder {}
|
||||||
|
|
||||||
impl ServeConfigBuilder {
|
impl ServeConfigBuilder {
|
||||||
/// Create a new ServeConfigBuilder with incremental static generation disabled and the default index.html settings
|
/// Create a new ServeConfigBuilder with incremental static generation disabled and the default index.html settings
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -239,6 +243,8 @@ pub struct ServeConfig {
|
||||||
pub(crate) incremental: Option<dioxus_isrg::IncrementalRendererConfig>,
|
pub(crate) incremental: Option<dioxus_isrg::IncrementalRendererConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LaunchConfig for ServeConfig {}
|
||||||
|
|
||||||
impl ServeConfig {
|
impl ServeConfig {
|
||||||
/// Create a new ServeConfig
|
/// Create a new ServeConfig
|
||||||
pub fn new() -> Result<Self, UnableToLoadIndex> {
|
pub fn new() -> Result<Self, UnableToLoadIndex> {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue