From 8da4c27bce89eef8399b78446eabbe5b840df9ce Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 19 Sep 2025 12:02:45 -0500 Subject: [PATCH 01/58] use the latest version of the cli --- Dockerfile | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f3bb6ed5d4..e117970be9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /app FROM chef AS planner COPY . . -RUN cargo binstall dioxus-cli --root /.cargo --no-confirm +RUN cargo binstall dioxus-cli --root /.cargo --no-confirm --version 0.7.0-rc.0 RUN cargo chef prepare --recipe-path recipe.json --bin server # Builder diff --git a/README.md b/README.md index 10467c5951..548db7a4fd 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ working `Rust` setup: ```sh -cargo binstall dioxus-cli@0.7.0-rc.0 --force +cargo binstall dioxus-cli@0.7.0-rc.0 --force --version 0.7.0-rc.0 ``` With [`dx`][dx] installed, you can use it to build and serve the documentation From 01dc03536bb7f70248397850cadf726680931d19 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 19 Sep 2025 12:19:25 -0500 Subject: [PATCH 02/58] Get the server compiling again --- .../playground/example-projects/src/lib.rs | 146 ++--- packages/playground/model/src/lib.rs | 262 ++++---- packages/playground/model/src/server.rs | 8 +- packages/playground/playground/src/lib.rs | 562 +++++++++--------- .../playground/playground/src/share_code.rs | 2 +- packages/playground/runner/src/main.rs | 118 ++-- packages/playground/server/src/main.rs | 384 ++++++------ packages/playground/server/src/ws.rs | 4 +- 8 files changed, 745 insertions(+), 741 deletions(-) diff --git a/packages/playground/example-projects/src/lib.rs b/packages/playground/example-projects/src/lib.rs index 2e9b351e23..4141bd8ad8 100644 --- a/packages/playground/example-projects/src/lib.rs +++ b/packages/playground/example-projects/src/lib.rs @@ -1,73 +1,73 @@ -// use include_dir::DirEntry; -// use model::Project; -// use once_cell::sync::Lazy; - -// static EXAMPLES: include_dir::Dir = include_dir::include_dir!("$CARGO_MANIFEST_DIR/examples"); - -// pub fn get_welcome_project() -> Project { -// get_example_projects() -// .iter() -// .find(|p| &p.path == "welcome.rs") -// .unwrap() -// .clone() -// } - -// /// Returns a list of all example projects. -// pub fn get_example_projects() -> &'static [Project] { -// static LIST: Lazy> = once_cell::sync::Lazy::new(|| { -// let mut projects = Vec::new(); - -// for entry in EXAMPLES.entries() { -// let DirEntry::File(entry) = entry else { -// continue; -// }; - -// let path = entry.path(); -// let contents = entry.contents(); -// let contents = String::from_utf8(contents.to_vec()).unwrap(); - -// let mut description = String::new(); - -// for line in contents.lines() { -// if let Some(line) = line.strip_prefix("//!") { -// description.push_str(line); -// description.push('\n'); -// } else { -// break; -// } -// } - -// // Remove the trailing newline -// description.pop(); - -// let mut project = Project::new( -// contents, -// Some(description), -// Some(path.to_string_lossy().to_string()), -// ); - -// project.prebuilt = true; - -// projects.push(project); -// } - -// projects -// }); - -// LIST.as_ref() -// } - -// #[cfg(test)] -// mod tests { -// use super::*; - -// #[test] -// fn has_projects() { -// assert!(!dbg!(get_example_projects()).is_empty()); -// } - -// #[test] -// fn has_welcome() { -// dbg!(get_welcome_project()); -// } -// } +use include_dir::DirEntry; +use model::Project; +use once_cell::sync::Lazy; + +static EXAMPLES: include_dir::Dir = include_dir::include_dir!("$CARGO_MANIFEST_DIR/examples"); + +pub fn get_welcome_project() -> Project { + get_example_projects() + .iter() + .find(|p| &p.path == "welcome.rs") + .unwrap() + .clone() +} + +/// Returns a list of all example projects. +pub fn get_example_projects() -> &'static [Project] { + static LIST: Lazy> = once_cell::sync::Lazy::new(|| { + let mut projects = Vec::new(); + + for entry in EXAMPLES.entries() { + let DirEntry::File(entry) = entry else { + continue; + }; + + let path = entry.path(); + let contents = entry.contents(); + let contents = String::from_utf8(contents.to_vec()).unwrap(); + + let mut description = String::new(); + + for line in contents.lines() { + if let Some(line) = line.strip_prefix("//!") { + description.push_str(line); + description.push('\n'); + } else { + break; + } + } + + // Remove the trailing newline + description.pop(); + + let mut project = Project::new( + contents, + Some(description), + Some(path.to_string_lossy().to_string()), + ); + + project.prebuilt = true; + + projects.push(project); + } + + projects + }); + + LIST.as_ref() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn has_projects() { + assert!(!dbg!(get_example_projects()).is_empty()); + } + + #[test] + fn has_welcome() { + dbg!(get_welcome_project()); + } +} diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index 6e571acfbf..e575c0a3e6 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -1,128 +1,134 @@ -// use serde::{Deserialize, Serialize}; -// use std::error::Error; -// use std::string::FromUtf8Error; -// use thiserror::Error; -// use uuid::Uuid; - -// pub mod api; - -// mod project; -// pub use project::Project; - -// #[cfg(feature = "server")] -// mod server; - -// #[cfg(feature = "web")] -// mod web; - -// #[derive(Debug, Serialize, Deserialize)] -// pub enum SocketMessage { -// BuildRequest(String), -// BuildFinished(Result), -// BuildStage(BuildStage), -// BuildDiagnostic(CargoDiagnostic), -// QueuePosition(usize), -// AlreadyConnected, -// } - -// /// A stage of building from the playground. -// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -// pub enum BuildStage { -// Compiling { -// crates_compiled: usize, -// total_crates: usize, -// current_crate: String, -// }, -// RunningBindgen, -// Other, -// } - -// impl SocketMessage { -// pub fn as_json_string(&self) -> Result { -// Ok(serde_json::to_string(self)?) -// } -// } - -// impl TryFrom for SocketMessage { -// type Error = SocketError; - -// fn try_from(value: String) -> Result { -// Ok(serde_json::from_str(&value)?) -// } -// } - -// /// A cargo diagnostic -// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -// pub struct CargoDiagnostic { -// pub target_crate: String, -// pub level: CargoLevel, -// pub message: String, -// pub spans: Vec, -// } - -// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -// pub enum CargoLevel { -// Error, -// Warning, -// } - -// #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -// pub struct CargoDiagnosticSpan { -// pub is_primary: bool, -// pub line_start: usize, -// pub line_end: usize, -// pub column_start: usize, -// pub column_end: usize, -// pub label: Option, -// } - -// /// Any socket error. -// #[derive(Debug, Error)] -// #[non_exhaustive] -// pub enum SocketError { -// #[error(transparent)] -// ParseJson(#[from] serde_json::Error), - -// #[error(transparent)] -// Utf8Decode(#[from] FromUtf8Error), - -// #[cfg(feature = "web")] -// #[error(transparent)] -// Gloo(#[from] gloo_net::websocket::WebSocketError), - -// #[cfg(feature = "server")] -// #[error(transparent)] -// Axum(#[from] axum::Error), -// } - -// /// Generic App Error -// #[derive(Debug, Error)] -// #[non_exhaustive] -// pub enum AppError { -// #[error("parse error: {0}")] -// Parse(Box), - -// #[error(transparent)] -// Request(#[from] reqwest::Error), - -// #[error("build is already running")] -// BuildIsAlreadyRunning, - -// #[error("resource not found")] -// ResourceNotFound, - -// // Web-specific errors -// #[cfg(feature = "web")] -// #[error(transparent)] -// Socket(#[from] SocketError), - -// #[cfg(feature = "web")] -// #[error(transparent)] -// Js(Box), -// } - -// impl From for AppError { -// fn from(value: serde_json::Error) -> Self { -// Self::Parse(Box::new(value)) -// } -// } +use serde::{Deserialize, Serialize}; +use std::error::Error; +use std::string::FromUtf8Error; +use thiserror::Error; +use uuid::Uuid; + +pub mod api; + +mod project; +pub use project::Project; + +#[cfg(feature = "server")] +mod server; + +#[cfg(feature = "web")] +mod web; + +#[derive(Debug, Serialize, Deserialize)] +pub enum SocketMessage { + BuildRequest(String), + BuildFinished(Result), + BuildStage(BuildStage), + BuildDiagnostic(CargoDiagnostic), + QueuePosition(usize), + AlreadyConnected, +} + +/// A stage of building from the playground. +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum BuildStage { + Compiling { + crates_compiled: usize, + total_crates: usize, + current_crate: String, + }, + RunningBindgen, + Other, +} + +impl SocketMessage { + pub fn as_json_string(&self) -> Result { + Ok(serde_json::to_string(self)?) + } +} + +impl TryFrom for SocketMessage { + type Error = SocketError; + + fn try_from(value: String) -> Result { + Ok(serde_json::from_str(&value)?) + } +} + +impl SocketMessage { + pub(crate) fn from_bytes>(value: B) -> Result { + Ok(serde_json::from_slice(value.as_ref())?) + } +} + +/// A cargo diagnostic +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CargoDiagnostic { + pub target_crate: String, + pub level: CargoLevel, + pub message: String, + pub spans: Vec, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum CargoLevel { + Error, + Warning, +} + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub struct CargoDiagnosticSpan { + pub is_primary: bool, + pub line_start: usize, + pub line_end: usize, + pub column_start: usize, + pub column_end: usize, + pub label: Option, +} + +/// Any socket error. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum SocketError { + #[error(transparent)] + ParseJson(#[from] serde_json::Error), + + #[error(transparent)] + Utf8Decode(#[from] FromUtf8Error), + + #[cfg(feature = "web")] + #[error(transparent)] + Gloo(#[from] gloo_net::websocket::WebSocketError), + + #[cfg(feature = "server")] + #[error(transparent)] + Axum(#[from] axum::Error), +} + +/// Generic App Error +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum AppError { + #[error("parse error: {0}")] + Parse(Box), + + #[error(transparent)] + Request(#[from] reqwest::Error), + + #[error("build is already running")] + BuildIsAlreadyRunning, + + #[error("resource not found")] + ResourceNotFound, + + // Web-specific errors + #[cfg(feature = "web")] + #[error(transparent)] + Socket(#[from] SocketError), + + #[cfg(feature = "web")] + #[error(transparent)] + Js(Box), +} + +impl From for AppError { + fn from(value: serde_json::Error) -> Self { + Self::Parse(Box::new(value)) + } +} diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 5d154851f8..157ff7c106 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -1,5 +1,7 @@ //! Server-specific implementations +use std::convert::Infallible; + use crate::{ AppError, BuildStage, CargoDiagnostic, CargoDiagnosticSpan, CargoLevel, SocketError, SocketMessage, @@ -36,7 +38,7 @@ impl SocketMessage { let msg = self .as_json_string() .expect("socket message should be valid json"); - ws::Message::Text(msg) + ws::Message::Text(msg.into()) } } @@ -44,8 +46,8 @@ impl TryFrom for SocketMessage { type Error = SocketError; fn try_from(value: ws::Message) -> Result { - let text = value.into_text()?; - SocketMessage::try_from(text) + let text = value.into_data(); + SocketMessage::from_bytes(text) } } diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index d4b8492543..6772f8acb5 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -1,281 +1,281 @@ -// use build::{start_build, BuildStage, BuildState}; -// use components::icons::Warning; -// use dioxus::logger::tracing::error; -// use dioxus::prelude::*; -// use dioxus_document::Link; -// // use dioxus_sdk::utils::timing::use_debounce; -// use editor::monaco::{self, monaco_loader_src, set_monaco_markers}; -// use hotreload::{attempt_hot_reload, HotReload}; -// use model::{api::ApiClient, AppError, Project, SocketError}; -// use std::time::Duration; - -// // #[cfg(target_arch = "wasm32")] -// // use dioxus_sdk::theme::{use_system_theme, SystemTheme}; - -// mod build; -// mod components; -// mod editor; -// mod hotreload; -// mod share_code; -// mod ws; - -// const DXP_CSS: Asset = asset!("/assets/dxp.css"); -// const MONACO_FOLDER: Asset = asset!("/assets/monaco-editor-0.52.2"); - -// /// The URLS that the playground should use for locating resources and services. -// #[derive(Debug, Clone, PartialEq)] -// pub struct PlaygroundUrls { -// /// The URL to the websocket server. -// pub socket: &'static str, -// /// The URL to the built project files from the server. -// pub server: &'static str, -// /// The url location of the playground UI: e.g. `https://dioxuslabs.com/play` -// pub location: &'static str, -// } - -// #[component] -// pub fn Playground( -// urls: PlaygroundUrls, -// share_code: ReadOnlySignal>, -// class: Option, -// ) -> Element { -// let mut build = use_context_provider(BuildState::new); -// let mut hot_reload = use_context_provider(HotReload::new); -// let api_client = use_context_provider(|| Signal::new(ApiClient::new(urls.server))); -// let mut errors = use_context_provider(Errors::new); - -// let monaco_ready = use_signal(|| false); -// let mut show_share_warning = use_signal(|| false); - -// // Default to the welcome project. -// // Project dirty determines whether the Rust-project is synced with the project in the editor. -// let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); -// let mut project_dirty = use_signal(|| false); -// use_effect(move || { -// if project_dirty() && monaco_ready() { -// let project = project.read(); -// monaco::set_current_model_value(&project.contents()); -// project_dirty.set(false); -// } -// }); - -// // Get the shared project if a share code was provided. -// use_effect(move || { -// if let Some(share_code) = share_code() { -// spawn(async move { -// let api_client = api_client(); -// let shared_project = Project::from_share_code(&api_client, share_code).await; -// if let Ok(shared_project) = shared_project { -// show_share_warning.set(true); -// project_dirty.set(true); -// project.set(shared_project); -// } -// }); -// } -// }); - -// // // Handle events when code changes. -// // let on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { -// // // Update the project -// // project.write().set_contents(new_code.clone()); -// // spawn(async move { -// // editor::monaco::set_markers(&[]); - -// // if build.stage().is_finished() { -// // attempt_hot_reload(hot_reload, &new_code); -// // } -// // }); -// // }); - -// // Handle setting diagnostics based on build state. -// use_effect(move || set_monaco_markers(build.diagnostics())); - -// // Themes -// #[cfg(target_arch = "wasm32")] -// let system_theme = use_system_theme(); -// use_effect(move || { -// #[cfg(target_arch = "wasm32")] -// editor::monaco::set_theme(system_theme().unwrap_or(SystemTheme::Light)); -// }); - -// // Handle starting a build. -// let on_rebuild = move |_| async move { -// if build.stage().is_running() || !monaco_ready() { -// return; -// } -// hot_reload.set_needs_rebuild(false); - -// // Update hot reload -// let code = editor::monaco::get_current_model_value(); - -// let socket_url = urls.socket.to_string(); -// match start_build(build, socket_url, code).await { -// Ok(success) => hot_reload.set_needs_rebuild(!success), -// Err(error) => errors.push_from_app_error(error), -// } -// }; - -// // Construct the full URL to the built project. -// let built_page_url = use_memo(move || { -// let prebuilt_id = project.read().prebuilt.then_some(project.read().id()); -// let local_id = build.stage().finished_id(); -// let id = local_id.or(prebuilt_id)?; -// Some(format!("{}/built/{}", urls.server, id)) -// }); - -// // State for pane resizing, shared by headers and panes. -// // The actual logic is in the panes component. -// let mut pane_left_width: Signal> = use_signal(|| None); -// let mut pane_right_width: Signal> = use_signal(|| None); - -// // Show the example list -// let show_examples = use_signal(|| true); -// use_effect(move || { -// let _show_examples = show_examples(); -// pane_left_width.set(None); -// pane_right_width.set(None); -// }); - -// rsx! { -// div { class, id: "dxp-playground-root", -// // Head elements -// Link { rel: "stylesheet", href: DXP_CSS } - -// // Monaco script -// script { -// src: monaco_loader_src(MONACO_FOLDER), -// onload: move |_| { -// #[cfg(target_arch = "wasm32")] -// monaco::on_monaco_load( -// MONACO_FOLDER, -// system_theme().unwrap_or(SystemTheme::Light), -// &project.read().contents(), -// hot_reload, -// monaco_ready, -// on_model_changed, -// ); -// }, -// } - -// // Share warning -// if show_share_warning() { -// components::Modal { -// icon: rsx! { -// Warning {} -// }, -// title: "Do you trust this code?", -// text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", -// ok_text: "I understand", -// on_ok: move |_| show_share_warning.set(false), -// } -// } - -// // Show errors one at a time. -// if let Some(error) = errors.first() { -// components::Modal { -// icon: rsx! { -// Warning {} -// }, -// title: "{error.0}", -// text: "{error.1}", -// on_ok: move |_| { -// errors.pop(); -// }, -// } -// } - -// // Playground UI -// components::Header { -// urls, -// on_rebuild, -// show_examples, -// pane_left_width, -// pane_right_width, -// file_name: project.read().path.clone(), -// } -// div { id: "dxp-lower-half", -// div { -// id: "dxp-examples-list", -// class: if show_examples() { "dxp-open" } else { "" }, -// for example in example_projects::get_example_projects().iter() { -// button { -// class: "dxp-example-project", -// onclick: move |_| { -// project.set(example.clone()); -// build.set_stage(BuildStage::Finished(Ok(example.id()))); -// monaco::set_current_model_value(&example.contents()); -// hot_reload.set_starting_code(&example.contents()); -// }, -// h3 { {example.path.clone()} } -// p { {example.description.clone()} } -// } -// } -// } -// components::Panes { -// pane_left_width, -// pane_right_width, -// built_page_url, -// } -// } - -// } -// } -// } - -// /// A helper type for gracefully handling app errors and logging them. -// #[derive(Clone, Copy)] -// pub struct Errors { -// errors: Signal>, -// } - -// impl Errors { -// pub fn new() -> Self { -// Self { -// errors: Signal::new(Vec::new()), -// } -// } - -// pub fn push_error(&mut self, error: (impl ToString, impl ToString)) { -// let error = (error.0.to_string(), error.1.to_string()); -// error!(?error, "an error occured and was handled gracefully"); -// self.errors.push(error); -// } - -// pub fn push_from_app_error(&mut self, app_error: AppError) { -// let error = match app_error { -// AppError::Parse(error) => ("Parse Error", error.to_string()), -// AppError::Request(error) => ("Request Error", error.to_string()), -// AppError::ResourceNotFound => ( -// "Resource Not Found", -// "A requested resource was not found.".to_string(), -// ), -// AppError::Socket(error) => ( -// "Socket Error", -// match error { -// SocketError::ParseJson(error) => error.to_string(), -// SocketError::Utf8Decode(_) => "UTF-8 decode failed".to_string(), -// SocketError::Gloo(web_socket_error) => web_socket_error.to_string(), -// e => e.to_string(), -// }, -// ), -// AppError::Js(error) => ("JS Error", error.to_string()), -// _ => return, -// }; - -// self.push_error(error); -// } - -// pub fn first(&self) -> Option<(String, String)> { -// self.errors.first().map(|x| x.clone()) -// } - -// pub fn pop(&mut self) -> Option<(String, String)> { -// self.errors.pop() -// } -// } - -// impl Default for Errors { -// fn default() -> Self { -// Self::new() -// } -// } +use build::{start_build, BuildStage, BuildState}; +use components::icons::Warning; +use dioxus::logger::tracing::error; +use dioxus::prelude::*; +use dioxus_document::Link; +// use dioxus_sdk::utils::timing::use_debounce; +use editor::monaco::{self, monaco_loader_src, set_monaco_markers}; +use hotreload::{attempt_hot_reload, HotReload}; +use model::{api::ApiClient, AppError, Project, SocketError}; +use std::time::Duration; + +// #[cfg(target_arch = "wasm32")] +// use dioxus_sdk::theme::{use_system_theme, SystemTheme}; + +mod build; +mod components; +mod editor; +mod hotreload; +mod share_code; +mod ws; + +const DXP_CSS: Asset = asset!("/assets/dxp.css"); +const MONACO_FOLDER: Asset = asset!("/assets/monaco-editor-0.52.2"); + +/// The URLS that the playground should use for locating resources and services. +#[derive(Debug, Clone, PartialEq)] +pub struct PlaygroundUrls { + /// The URL to the websocket server. + pub socket: &'static str, + /// The URL to the built project files from the server. + pub server: &'static str, + /// The url location of the playground UI: e.g. `https://dioxuslabs.com/play` + pub location: &'static str, +} + +#[component] +pub fn Playground( + urls: PlaygroundUrls, + share_code: ReadOnlySignal>, + class: Option, +) -> Element { + let mut build = use_context_provider(BuildState::new); + let mut hot_reload = use_context_provider(HotReload::new); + let api_client = use_context_provider(|| Signal::new(ApiClient::new(urls.server))); + let mut errors = use_context_provider(Errors::new); + + let monaco_ready = use_signal(|| false); + let mut show_share_warning = use_signal(|| false); + + // Default to the welcome project. + // Project dirty determines whether the Rust-project is synced with the project in the editor. + let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); + let mut project_dirty = use_signal(|| false); + use_effect(move || { + if project_dirty() && monaco_ready() { + let project = project.read(); + monaco::set_current_model_value(&project.contents()); + project_dirty.set(false); + } + }); + + // Get the shared project if a share code was provided. + use_effect(move || { + if let Some(share_code) = share_code() { + spawn(async move { + let api_client = api_client(); + let shared_project = Project::from_share_code(&api_client, share_code).await; + if let Ok(shared_project) = shared_project { + show_share_warning.set(true); + project_dirty.set(true); + project.set(shared_project); + } + }); + } + }); + + // // Handle events when code changes. + // let on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { + // // Update the project + // project.write().set_contents(new_code.clone()); + // spawn(async move { + // editor::monaco::set_markers(&[]); + + // if build.stage().is_finished() { + // attempt_hot_reload(hot_reload, &new_code); + // } + // }); + // }); + + // Handle setting diagnostics based on build state. + use_effect(move || set_monaco_markers(build.diagnostics())); + + // Themes + #[cfg(target_arch = "wasm32")] + let system_theme = use_system_theme(); + use_effect(move || { + #[cfg(target_arch = "wasm32")] + editor::monaco::set_theme(system_theme().unwrap_or(SystemTheme::Light)); + }); + + // Handle starting a build. + let on_rebuild = move |_| async move { + if build.stage().is_running() || !monaco_ready() { + return; + } + hot_reload.set_needs_rebuild(false); + + // Update hot reload + let code = editor::monaco::get_current_model_value(); + + let socket_url = urls.socket.to_string(); + match start_build(build, socket_url, code).await { + Ok(success) => hot_reload.set_needs_rebuild(!success), + Err(error) => errors.push_from_app_error(error), + } + }; + + // Construct the full URL to the built project. + let built_page_url = use_memo(move || { + let prebuilt_id = project.read().prebuilt.then_some(project.read().id()); + let local_id = build.stage().finished_id(); + let id = local_id.or(prebuilt_id)?; + Some(format!("{}/built/{}", urls.server, id)) + }); + + // State for pane resizing, shared by headers and panes. + // The actual logic is in the panes component. + let mut pane_left_width: Signal> = use_signal(|| None); + let mut pane_right_width: Signal> = use_signal(|| None); + + // Show the example list + let show_examples = use_signal(|| true); + use_effect(move || { + let _show_examples = show_examples(); + pane_left_width.set(None); + pane_right_width.set(None); + }); + + rsx! { + div { class, id: "dxp-playground-root", + // Head elements + Link { rel: "stylesheet", href: DXP_CSS } + + // Monaco script + script { + src: monaco_loader_src(MONACO_FOLDER), + onload: move |_| { + #[cfg(target_arch = "wasm32")] + monaco::on_monaco_load( + MONACO_FOLDER, + system_theme().unwrap_or(SystemTheme::Light), + &project.read().contents(), + hot_reload, + monaco_ready, + on_model_changed, + ); + }, + } + + // Share warning + if show_share_warning() { + components::Modal { + icon: rsx! { + Warning {} + }, + title: "Do you trust this code?", + text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", + ok_text: "I understand", + on_ok: move |_| show_share_warning.set(false), + } + } + + // Show errors one at a time. + if let Some(error) = errors.first() { + components::Modal { + icon: rsx! { + Warning {} + }, + title: "{error.0}", + text: "{error.1}", + on_ok: move |_| { + errors.pop(); + }, + } + } + + // Playground UI + components::Header { + urls, + on_rebuild, + show_examples, + pane_left_width, + pane_right_width, + file_name: project.read().path.clone(), + } + div { id: "dxp-lower-half", + div { + id: "dxp-examples-list", + class: if show_examples() { "dxp-open" } else { "" }, + for example in example_projects::get_example_projects().iter() { + button { + class: "dxp-example-project", + onclick: move |_| { + project.set(example.clone()); + build.set_stage(BuildStage::Finished(Ok(example.id()))); + monaco::set_current_model_value(&example.contents()); + hot_reload.set_starting_code(&example.contents()); + }, + h3 { {example.path.clone()} } + p { {example.description.clone()} } + } + } + } + components::Panes { + pane_left_width, + pane_right_width, + built_page_url, + } + } + + } + } +} + +/// A helper type for gracefully handling app errors and logging them. +#[derive(Clone, Copy)] +pub struct Errors { + errors: Signal>, +} + +impl Errors { + pub fn new() -> Self { + Self { + errors: Signal::new(Vec::new()), + } + } + + pub fn push_error(&mut self, error: (impl ToString, impl ToString)) { + let error = (error.0.to_string(), error.1.to_string()); + error!(?error, "an error occured and was handled gracefully"); + self.errors.push(error); + } + + pub fn push_from_app_error(&mut self, app_error: AppError) { + let error = match app_error { + AppError::Parse(error) => ("Parse Error", error.to_string()), + AppError::Request(error) => ("Request Error", error.to_string()), + AppError::ResourceNotFound => ( + "Resource Not Found", + "A requested resource was not found.".to_string(), + ), + AppError::Socket(error) => ( + "Socket Error", + match error { + SocketError::ParseJson(error) => error.to_string(), + SocketError::Utf8Decode(_) => "UTF-8 decode failed".to_string(), + SocketError::Gloo(web_socket_error) => web_socket_error.to_string(), + e => e.to_string(), + }, + ), + AppError::Js(error) => ("JS Error", error.to_string()), + _ => return, + }; + + self.push_error(error); + } + + pub fn first(&self) -> Option<(String, String)> { + self.errors.first().map(|x| x.clone()) + } + + pub fn pop(&mut self) -> Option<(String, String)> { + self.errors.pop() + } +} + +impl Default for Errors { + fn default() -> Self { + Self::new() + } +} diff --git a/packages/playground/playground/src/share_code.rs b/packages/playground/playground/src/share_code.rs index 4192cf4e10..60344cd2e0 100644 --- a/packages/playground/playground/src/share_code.rs +++ b/packages/playground/playground/src/share_code.rs @@ -1,4 +1,4 @@ -use dioxus::signals::{Signal, Writable}; +use dioxus::signals::{Signal, Writable, WritableExt}; use dioxus_document::eval; use model::{api::ApiClient, AppError, Project}; diff --git a/packages/playground/runner/src/main.rs b/packages/playground/runner/src/main.rs index 1df10b000a..6574ca8e51 100644 --- a/packages/playground/runner/src/main.rs +++ b/packages/playground/runner/src/main.rs @@ -1,60 +1,58 @@ -// // TODO: Remove public folder with monaco in it (once manganis folder dir works) - -// use dioxus::logger::tracing::Level; -// use dioxus::prelude::*; -// use dioxus_playground::{Playground, PlaygroundUrls}; - -// #[cfg(not(feature = "real-server"))] -// const URLS: PlaygroundUrls = PlaygroundUrls { -// socket: "ws://localhost:3000/ws", -// server: "http://localhost:3000", -// location: "http://localhost:8080", -// }; - -// #[cfg(feature = "real-server")] -// const URLS: PlaygroundUrls = PlaygroundUrls { -// socket: "wss://docsite-playground.fly.dev/ws", -// server: "https://docsite-playground.fly.dev", -// location: "https://dioxuslabs.com/playground", -// }; - -// // Runner-only styling -// const MAIN_CSS: Asset = asset!("/src/main.css"); - -// #[derive(Routable, PartialEq, Clone)] -// enum Route { -// #[route("/")] -// DefaultPlayground {}, - -// #[route("/shared/:share_code")] -// SharePlayground { share_code: String }, -// } - -// fn main() { -// dioxus::logger::init(Level::INFO).expect("failed to start logger"); -// dioxus::launch(App); -// } - -// #[component] -// fn App() -> Element { -// rsx! { -// document::Link { rel: "stylesheet", href: MAIN_CSS } -// Router:: {} -// } -// } - -// #[component] -// fn DefaultPlayground() -> Element { -// rsx! { -// Playground { urls: URLS, class: "playground-container" } -// } -// } - -// #[component] -// fn SharePlayground(share_code: ReadOnlySignal>) -> Element { -// rsx! { -// Playground { urls: URLS, share_code, class: "playground-container" } -// } -// } - -fn main() {} +// TODO: Remove public folder with monaco in it (once manganis folder dir works) + +use dioxus::logger::tracing::Level; +use dioxus::prelude::*; +use dioxus_playground::{Playground, PlaygroundUrls}; + +#[cfg(not(feature = "real-server"))] +const URLS: PlaygroundUrls = PlaygroundUrls { + socket: "ws://localhost:3000/ws", + server: "http://localhost:3000", + location: "http://localhost:8080", +}; + +#[cfg(feature = "real-server")] +const URLS: PlaygroundUrls = PlaygroundUrls { + socket: "wss://docsite-playground.fly.dev/ws", + server: "https://docsite-playground.fly.dev", + location: "https://dioxuslabs.com/playground", +}; + +// Runner-only styling +const MAIN_CSS: Asset = asset!("/src/main.css"); + +#[derive(Routable, PartialEq, Clone)] +enum Route { + #[route("/")] + DefaultPlayground {}, + + #[route("/shared/:share_code")] + SharePlayground { share_code: String }, +} + +fn main() { + dioxus::logger::init(Level::INFO).expect("failed to start logger"); + dioxus::launch(App); +} + +#[component] +fn App() -> Element { + rsx! { + document::Link { rel: "stylesheet", href: MAIN_CSS } + Router:: {} + } +} + +#[component] +fn DefaultPlayground() -> Element { + rsx! { + Playground { urls: URLS, class: "playground-container" } + } +} + +#[component] +fn SharePlayground(share_code: ReadOnlySignal>) -> Element { + rsx! { + Playground { urls: URLS, share_code, class: "playground-container" } + } +} diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index d5b2965a3e..0a94870292 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -1,193 +1,191 @@ -// use app::AppState; -// use axum::{ -// error_handling::HandleErrorLayer, -// extract::{Request, State}, -// http::StatusCode, -// middleware::{self, Next}, -// response::{Redirect, Response}, -// routing::{get, post}, -// BoxError, Router, -// }; -// use axum_client_ip::SecureClientIpSource; -// use dioxus_logger::tracing::{error, info, warn, Level}; -// use share::{get_shared_project, share_project}; -// use std::{io, net::SocketAddr, sync::atomic::Ordering, time::Duration}; -// use tokio::{net::TcpListener, select, time::Instant}; -// use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder}; -// use tower_http::{compression::CompressionLayer, cors::CorsLayer}; - -// mod app; -// mod build; -// mod serve; -// mod share; -// mod ws; - -// /// Rate limiter configuration. -// /// How many requests each user should get within a time period. -// const REQUESTS_PER_INTERVAL: u64 = 30; -// /// The period of time after the request limit resets. -// const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); - -// #[tokio::main] -// async fn main() { -// dioxus_logger::init(Level::INFO).expect("failed to init logger"); - -// let state = AppState::new().await; -// let port = state.env.port; - -// let secure_ip_src = match state.env.production { -// true => SecureClientIpSource::FlyClientIp, -// false => SecureClientIpSource::ConnectInfo, -// }; - -// // Build the routers. -// let built_router = Router::new() -// .route("/", get(serve::serve_built_index)) -// .route("/*file_path", get(serve::serve_other_built)); - -// let shared_router = Router::new() -// .route("/", post(share_project)) -// .route("/:id", get(get_shared_project)); - -// let app = Router::new() -// .route("/ws", get(ws::ws_handler)) -// .nest("/built/:build_id", built_router) -// .nest("/shared", shared_router) -// .route( -// "/", -// get(|| async { Redirect::permanent("https://dioxuslabs.com/play") }), -// ) -// .route("/health", get(|| async { StatusCode::OK })) -// .layer( -// ServiceBuilder::new() -// .layer(HandleErrorLayer::new(|error: BoxError| async move { -// error!(?error, "unhandled server error"); -// (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error") -// })) -// .layer(CompressionLayer::new()) -// .layer(CorsLayer::very_permissive()) -// .layer(BufferLayer::new(1024)) -// .layer(RateLimitLayer::new( -// REQUESTS_PER_INTERVAL, -// RATE_LIMIT_INTERVAL, -// )) -// .layer(secure_ip_src.into_extension()) -// .layer(middleware::from_fn_with_state( -// state.clone(), -// request_counter, -// )), -// ) -// .with_state(state); - -// // Start the Axum server. -// let final_address = &format!("0.0.0.0:{port}"); -// let listener = TcpListener::bind(final_address).await.unwrap(); - -// info!("listening on `{}`", final_address); -// axum::serve( -// listener, -// app.into_make_service_with_connect_info::(), -// ) -// .await -// .unwrap(); -// } - -// /// Start misc services for maintaining the server's operation. -// fn start_cleanup_services(state: AppState) { -// tokio::task::spawn(async move { -// let cleanup_delay = state.env.built_cleanup_delay; -// let shutdown_delay = state -// .env -// .shutdown_delay -// .unwrap_or(Duration::from_secs(99999999)); - -// loop { -// let now = Instant::now(); -// let next_shutdown_check = now + shutdown_delay; -// let next_cleanup_check = now + cleanup_delay; - -// select! { -// // Perform the next built project cleanup. -// _ = tokio::time::sleep_until(next_cleanup_check) => { -// if let Err(e) = check_cleanup(state.clone()).await { -// warn!("failed to clean built projects: {e}"); -// } -// } - -// // Check if server should shut down. -// _ = tokio::time::sleep_until(next_shutdown_check), if state.env.shutdown_delay.is_some() => { -// let should_shutdown = check_shutdown(&state, &shutdown_delay).await; -// if should_shutdown { -// // TODO: We could be more graceful here. -// std::process::exit(0); -// } -// } -// } -// } -// }); -// } - -// /// Check and cleanup any expired built projects. -// async fn check_cleanup(state: AppState) -> Result<(), io::Error> { -// let task = tokio::task::spawn_blocking(move || { -// let dir = std::fs::read_dir(state.env.built_path)?; - -// for item in dir { -// let item = item?; -// let path = item.path(); -// let pathname = path.file_name().unwrap().to_string_lossy(); - -// // Always cache the examples - don't remove those. -// if example_projects::get_example_projects() -// .iter() -// .any(|p| p.id().to_string() == pathname) -// { -// continue; -// } - -// let time_elapsed = item -// .metadata() -// .and_then(|m| m.created()) -// .and_then(|c| c.elapsed().map_err(io::Error::other))?; - -// if time_elapsed >= state.env.built_cleanup_delay { -// std::fs::remove_dir_all(path)?; -// } -// } - -// Ok(()) -// }); - -// task.await.expect("task should not panic or abort") -// } - -// /// Check if the server should shutdown. -// async fn check_shutdown(state: &AppState, shutdown_delay: &Duration) -> bool { -// let now = Instant::now(); -// let mut last_req_time = state.last_request_time.lock().await; - -// // Reset timer when build is occuring. -// if state.is_building.load(Ordering::SeqCst) { -// *last_req_time = now; -// return false; -// } - -// // Exit program if not building and duration exceeds shutdown time. -// let duration_since_req = now.duration_since(*last_req_time); -// if duration_since_req.as_secs() >= shutdown_delay.as_secs() { -// return true; -// } - -// false -// } - -// /// A middleware that counts the time since the last request for the shutdown watcher. -// async fn request_counter(State(state): State, req: Request, next: Next) -> Response { -// let now = Instant::now(); -// let mut lock = state.last_request_time.lock().await; -// *lock = now; -// drop(lock); -// next.run(req).await -// } - -fn main() {} +use app::AppState; +use axum::{ + error_handling::HandleErrorLayer, + extract::{Request, State}, + http::StatusCode, + middleware::{self, Next}, + response::{Redirect, Response}, + routing::{get, post}, + BoxError, Router, +}; +use axum_client_ip::ClientIpSource; +use dioxus_logger::tracing::{error, info, warn, Level}; +use share::{get_shared_project, share_project}; +use std::{io, net::SocketAddr, sync::atomic::Ordering, time::Duration}; +use tokio::{net::TcpListener, select, time::Instant}; +use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder}; +use tower_http::{compression::CompressionLayer, cors::CorsLayer}; + +mod app; +mod build; +mod serve; +mod share; +mod ws; + +/// Rate limiter configuration. +/// How many requests each user should get within a time period. +const REQUESTS_PER_INTERVAL: u64 = 30; +/// The period of time after the request limit resets. +const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); + +#[tokio::main] +async fn main() { + dioxus_logger::init(Level::INFO).expect("failed to init logger"); + + let state = AppState::new().await; + let port = state.env.port; + + let secure_ip_src = match state.env.production { + true => ClientIpSource::FlyClientIp, + false => ClientIpSource::ConnectInfo, + }; + + // Build the routers. + let built_router = Router::new() + .route("/", get(serve::serve_built_index)) + .route("/{*file_path}", get(serve::serve_other_built)); + + let shared_router = Router::new() + .route("/", post(share_project)) + .route("/{:id}", get(get_shared_project)); + + let app = Router::new() + .route("/ws", get(ws::ws_handler)) + .nest("/built/{:build_id}", built_router) + .nest("/shared", shared_router) + .route( + "/", + get(|| async { Redirect::permanent("https://dioxuslabs.com/play") }), + ) + .route("/health", get(|| async { StatusCode::OK })) + .layer( + ServiceBuilder::new() + .layer(HandleErrorLayer::new(|error: BoxError| async move { + error!(?error, "unhandled server error"); + (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error") + })) + .layer(CompressionLayer::new()) + .layer(CorsLayer::very_permissive()) + .layer(BufferLayer::new(1024)) + .layer(RateLimitLayer::new( + REQUESTS_PER_INTERVAL, + RATE_LIMIT_INTERVAL, + )) + .layer(secure_ip_src.into_extension()) + .layer(middleware::from_fn_with_state( + state.clone(), + request_counter, + )), + ) + .with_state(state); + + // Start the Axum server. + let final_address = &format!("0.0.0.0:{port}"); + let listener = TcpListener::bind(final_address).await.unwrap(); + + info!("listening on `{}`", final_address); + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .await + .unwrap(); +} + +/// Start misc services for maintaining the server's operation. +fn start_cleanup_services(state: AppState) { + tokio::task::spawn(async move { + let cleanup_delay = state.env.built_cleanup_delay; + let shutdown_delay = state + .env + .shutdown_delay + .unwrap_or(Duration::from_secs(99999999)); + + loop { + let now = Instant::now(); + let next_shutdown_check = now + shutdown_delay; + let next_cleanup_check = now + cleanup_delay; + + select! { + // Perform the next built project cleanup. + _ = tokio::time::sleep_until(next_cleanup_check) => { + if let Err(e) = check_cleanup(state.clone()).await { + warn!("failed to clean built projects: {e}"); + } + } + + // Check if server should shut down. + _ = tokio::time::sleep_until(next_shutdown_check), if state.env.shutdown_delay.is_some() => { + let should_shutdown = check_shutdown(&state, &shutdown_delay).await; + if should_shutdown { + // TODO: We could be more graceful here. + std::process::exit(0); + } + } + } + } + }); +} + +/// Check and cleanup any expired built projects. +async fn check_cleanup(state: AppState) -> Result<(), io::Error> { + let task = tokio::task::spawn_blocking(move || { + let dir = std::fs::read_dir(state.env.built_path)?; + + for item in dir { + let item = item?; + let path = item.path(); + let pathname = path.file_name().unwrap().to_string_lossy(); + + // Always cache the examples - don't remove those. + if example_projects::get_example_projects() + .iter() + .any(|p| p.id().to_string() == pathname) + { + continue; + } + + let time_elapsed = item + .metadata() + .and_then(|m| m.created()) + .and_then(|c| c.elapsed().map_err(io::Error::other))?; + + if time_elapsed >= state.env.built_cleanup_delay { + std::fs::remove_dir_all(path)?; + } + } + + Ok(()) + }); + + task.await.expect("task should not panic or abort") +} + +/// Check if the server should shutdown. +async fn check_shutdown(state: &AppState, shutdown_delay: &Duration) -> bool { + let now = Instant::now(); + let mut last_req_time = state.last_request_time.lock().await; + + // Reset timer when build is occuring. + if state.is_building.load(Ordering::SeqCst) { + *last_req_time = now; + return false; + } + + // Exit program if not building and duration exceeds shutdown time. + let duration_since_req = now.duration_since(*last_req_time); + if duration_since_req.as_secs() >= shutdown_delay.as_secs() { + return true; + } + + false +} + +/// A middleware that counts the time since the last request for the shutdown watcher. +async fn request_counter(State(state): State, req: Request, next: Next) -> Response { + let now = Instant::now(); + let mut lock = state.last_request_time.lock().await; + *lock = now; + drop(lock); + next.run(req).await +} diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index 8de3398610..81b9acc961 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -6,7 +6,7 @@ use axum::{ extract::{ws::WebSocket, State, WebSocketUpgrade}, response::IntoResponse, }; -use axum_client_ip::SecureClientIp; +use axum_client_ip::ClientIp; use dioxus_logger::tracing::error; use futures::{SinkExt, StreamExt as _}; use model::{Project, SocketMessage}; @@ -18,7 +18,7 @@ use tokio::{ /// Handle any pre-websocket processing. pub async fn ws_handler( State(state): State, - SecureClientIp(ip): SecureClientIp, + ClientIp(ip): ClientIp, ws: WebSocketUpgrade, ) -> impl IntoResponse { let ip = ip.to_string(); From bc5967babfe3667a4f8cb8d72907269418f02097 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 22 Sep 2025 08:41:45 -0500 Subject: [PATCH 03/58] playground and server running --- Cargo.lock | 64 ++++++++++++++++ Cargo.toml | 65 +++------------- packages/docsite/Cargo.toml | 2 +- packages/docsite/src/components.rs | 4 +- packages/docsite/src/components/playground.rs | 15 ++-- packages/playground/playground/Cargo.toml | 2 +- .../playground/src/editor/monaco.rs | 74 +++++++++---------- packages/playground/playground/src/lib.rs | 34 ++++----- 8 files changed, 138 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e77346572..9551e63fc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1801,6 +1801,7 @@ dependencies = [ "dioxus-rsx", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", + "dioxus-sdk", "example-projects", "futures", "gloo-net", @@ -1899,6 +1900,16 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "dioxus-sdk" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +dependencies = [ + "dioxus-time", + "dioxus-util", + "dioxus-window", +] + [[package]] name = "dioxus-search" version = "0.1.0" @@ -2043,6 +2054,26 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "dioxus-time" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +dependencies = [ + "dioxus", + "futures", + "gloo-timers", + "tokio", +] + +[[package]] +name = "dioxus-util" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +dependencies = [ + "dioxus", + "serde", +] + [[package]] name = "dioxus-web" version = "0.7.0-rc.0" @@ -2076,6 +2107,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-window" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +dependencies = [ + "dioxus", + "dioxus-config-macro", + "dioxus-desktop", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "dioxus_docs_site" version = "0.0.0" @@ -2093,6 +2136,7 @@ dependencies = [ "dioxus-docs-07", "dioxus-docs-blog", "dioxus-docs-examples", + "dioxus-playground", "dioxus-search", "dioxus-web", "futures", @@ -8492,3 +8536,23 @@ dependencies = [ "syn 2.0.106", "winnow 0.7.13", ] + +[[patch.unused]] +name = "dioxus-geolocation" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" + +[[patch.unused]] +name = "dioxus-notification" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" + +[[patch.unused]] +name = "dioxus-sync" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" + +[[patch.unused]] +name = "dioxus_storage" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" diff --git a/Cargo.toml b/Cargo.toml index 6e36485c59..5392efb342 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ dioxus-dx-wire-format = "0.7.0-rc.0" dioxus-logger = "0.7.0-rc.0" # 3rd-party dioxus -# dioxus-sdk = { version = "0.6", default-features = false } +dioxus-sdk = { version = "0.7.0-rc.0", default-features = false } getrandom = { version = "0.2" } serde = { version = "1.0.215", features = ["derive"] } @@ -121,58 +121,11 @@ codegen-units = 1 [patch.crates-io] -# dioxus = { path = "../dioxus/packages/dioxus" } -# dioxus-lib = { path = "../dioxus/packages/dioxus-lib" } -# dioxus-core = { path = "../dioxus/packages/core" } -# dioxus-core-macro = { path = "../dioxus/packages/core-macro" } -# dioxus-config-macro = { path = "../dioxus/packages/config-macro" } -# dioxus-router = { path = "../dioxus/packages/router" } -# dioxus-router-macro = { path = "../dioxus/packages/router-macro" } -# dioxus-html = { path = "../dioxus/packages/html" } -# dioxus-html-internal-macro = { path = "../dioxus/packages/html-internal-macro" } -# dioxus-hooks = { path = "../dioxus/packages/hooks" } -# dioxus-web = { path = "../dioxus/packages/web" } -# dioxus-ssr = { path = "../dioxus/packages/ssr" } -# dioxus-desktop = { path = "../dioxus/packages/desktop" } -# dioxus-interpreter-js = { path = "../dioxus/packages/interpreter" } -# dioxus-liveview = { path = "../dioxus/packages/liveview" } -# dioxus-rsx = { path = "../dioxus/packages/rsx" } -# dioxus-signals = { path = "../dioxus/packages/signals" } -# dioxus-cli-config = { path = "../dioxus/packages/cli-config" } -# generational-box = { path = "../dioxus/packages/generational-box" } -# dioxus_server_macro = { path = "../dioxus/packages/server-macro" } -# dioxus-fullstack = { path = "../dioxus/packages/fullstack" } -# dioxus-autofmt = { path = "../dioxus/packages/autofmt" } -# dioxus-devtools = { path = "../dioxus/packages/devtools" } -# dioxus-devtools-types = { path = "../dioxus/packages/devtools-types" } -# manganis = { path = "../dioxus/packages/manganis/manganis" } -# manganis-core = { path = "../dioxus/packages/manganis/manganis-core" } -# manganis-macro = { path = "../dioxus/packages/manganis/manganis-macro" } - -# dioxus = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-lib = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-core = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-core-macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-config-macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-router = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-router-macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-html = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-html-internal-macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-hooks = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-web = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-ssr = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-desktop = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-interpreter-js = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-liveview = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-rsx = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# generational-box = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus_server_macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-fullstack = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-autofmt = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-devtools = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# dioxus-devtools-types = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# manganis = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# manganis-core = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } -# manganis-macro = { git = "https://github.com/dioxuslabs/dioxus", rev ="e00ebec8048d8ca934fff918d2d1432bf6ce7640" } +dioxus-geolocation = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-notification = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus_storage = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-sync = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-time = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-util = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } diff --git a/packages/docsite/Cargo.toml b/packages/docsite/Cargo.toml index cbcb9037ac..ae52432493 100644 --- a/packages/docsite/Cargo.toml +++ b/packages/docsite/Cargo.toml @@ -24,7 +24,7 @@ syntect-html = { workspace = true } mdbook-shared = { workspace = true } use-mdbook = { workspace = true } dioxus-search = { workspace = true } -# dioxus-playground = { workspace = true } +dioxus-playground = { workspace = true } askama_escape = { version = "0.10.3", optional = true } getrandom = { workspace = true, features = ["js"] } diff --git a/packages/docsite/src/components.rs b/packages/docsite/src/components.rs index 466b73dd3a..ce2985c5c9 100644 --- a/packages/docsite/src/components.rs +++ b/packages/docsite/src/components.rs @@ -14,8 +14,8 @@ pub mod nav; pub use nav::*; pub mod notfound; pub use notfound::*; -// pub mod playground; -// pub use playground::*; +pub mod playground; +pub use playground::*; pub mod search; pub use search::*; pub mod component_demo; diff --git a/packages/docsite/src/components/playground.rs b/packages/docsite/src/components/playground.rs index 581e37f018..0881950fd2 100644 --- a/packages/docsite/src/components/playground.rs +++ b/packages/docsite/src/components/playground.rs @@ -4,14 +4,14 @@ use dioxus_playground::PlaygroundUrls; #[cfg(not(feature = "production"))] const URLS: PlaygroundUrls = PlaygroundUrls { socket: "ws://localhost:3000/ws", - built: "http://localhost:3000/built/", + server: "http://localhost:3000/built/", location: "http://localhost:8080", }; #[cfg(feature = "production")] const URLS: PlaygroundUrls = PlaygroundUrls { socket: "wss://docsite-playground.fly.dev/ws", - built: "https://docsite-playground.fly.dev/built/", + server: "https://docsite-playground.fly.dev/built/", location: "https://dioxuslabs.com/playground", }; @@ -21,12 +21,6 @@ pub fn Playground(share_code: Option) -> Element { let mut on_client = use_signal(|| false); use_effect(move || on_client.set(true)); - // dioxus_playground::Playground { - // class: "playground-container max-w-screen-2xl mx-auto mt-8", - // urls: URLS, - // share_code, - // } - if on_client() { rsx! { ErrorBoundary { @@ -48,6 +42,11 @@ pub fn Playground(share_code: Option) -> Element { } } }, + dioxus_playground::Playground { + class: "playground-container max-w-screen-2xl mx-auto mt-8", + urls: URLS, + share_code, + } } } } else { diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index 89562b9e4c..622fb1c88e 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -16,7 +16,7 @@ thiserror = { workspace = true } # Dioxus dioxus = { workspace = true, features = ["web"] } dioxus-document = { workspace = true } -# dioxus-sdk = { workspace = true, features = [ "window_size", "timing", ] } +dioxus-sdk = { workspace = true, features = ["util", "time", "window"] } # Hot reload / Paste as RSX dioxus-core = { workspace = true } diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index 4d413c9ce5..d22d0bc9b3 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -1,12 +1,12 @@ use crate::hotreload::HotReload; use dioxus::prelude::*; -// use dioxus_sdk::utils::timing::UseDebounce; +use dioxus_sdk::time::UseDebounce; use model::{CargoDiagnostic, CargoLevel}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -// #[cfg(target_arch = "wasm32")] -// use dioxus_sdk::theme::SystemTheme; +#[cfg(target_arch = "wasm32")] +use dioxus_sdk::window::theme::Theme; /// Get the path prefix for the `/vs` folder inside the Monaco folder. pub fn monaco_vs_prefix(folder: Asset) -> String { @@ -52,35 +52,35 @@ pub fn set_monaco_markers(diagnostics: Signal>) { set_markers(&markers); } -// /// Initialize Monaco once the loader script loads. -// #[cfg(target_arch = "wasm32")] -// pub fn on_monaco_load( -// folder: Asset, -// system_theme: SystemTheme, -// contents: &str, -// mut hot_reload: HotReload, -// mut monaco_ready: Signal, -// mut on_model_changed: UseDebounce, -// ) { -// let on_ready_callback = Closure::new(move || monaco_ready.set(true)); -// let monaco_prefix = monaco_vs_prefix(folder); -// init( -// &monaco_prefix, -// super::EDITOR_ELEMENT_ID, -// system_theme, -// contents, -// &on_ready_callback, -// ); - -// hot_reload.set_starting_code(contents); - -// let model_change_callback = -// Closure::new(move |new_code: String| on_model_changed.action(new_code)); -// register_model_change_event(&model_change_callback); - -// on_ready_callback.forget(); -// model_change_callback.forget(); -// } +/// Initialize Monaco once the loader script loads. +#[cfg(target_arch = "wasm32")] +pub fn on_monaco_load( + folder: Asset, + system_theme: Theme, + contents: &str, + mut hot_reload: HotReload, + mut monaco_ready: Signal, + mut on_model_changed: UseDebounce, +) { + let on_ready_callback = Closure::new(move || monaco_ready.set(true)); + let monaco_prefix = monaco_vs_prefix(folder); + init( + &monaco_prefix, + super::EDITOR_ELEMENT_ID, + system_theme, + contents, + &on_ready_callback, + ); + + hot_reload.set_starting_code(contents); + + let model_change_callback = + Closure::new(move |new_code: String| on_model_changed.action(new_code)); + register_model_change_event(&model_change_callback); + + on_ready_callback.forget(); + model_change_callback.forget(); +} #[derive(Serialize, Deserialize, Clone)] pub struct Marker { @@ -151,7 +151,7 @@ extern "C" { pub fn init( vs_path_prefix: &str, element_id: &str, - initial_theme: SystemTheme, + initial_theme: Theme, initial_snippet: &str, on_ready_callback: &Closure, ) { @@ -167,7 +167,7 @@ pub fn init( } #[cfg(target_arch = "wasm32")] -pub fn set_theme(theme: SystemTheme) { +pub fn set_theme(theme: Theme) { let theme = system_theme_to_string(theme); set_monaco_theme(&theme); } @@ -184,10 +184,10 @@ fn register_paste_as_rsx_action() { } #[cfg(target_arch = "wasm32")] -fn system_theme_to_string(theme: SystemTheme) -> String { +fn system_theme_to_string(theme: Theme) -> String { match theme { - SystemTheme::Light => "dx-vs", - SystemTheme::Dark => "dx-vs-dark", + Theme::Light => "dx-vs", + Theme::Dark => "dx-vs-dark", } .to_string() } diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 6772f8acb5..cf4933ef57 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -3,14 +3,14 @@ use components::icons::Warning; use dioxus::logger::tracing::error; use dioxus::prelude::*; use dioxus_document::Link; -// use dioxus_sdk::utils::timing::use_debounce; +use dioxus_sdk::time::use_debounce; use editor::monaco::{self, monaco_loader_src, set_monaco_markers}; use hotreload::{attempt_hot_reload, HotReload}; use model::{api::ApiClient, AppError, Project, SocketError}; use std::time::Duration; -// #[cfg(target_arch = "wasm32")] -// use dioxus_sdk::theme::{use_system_theme, SystemTheme}; +#[cfg(target_arch = "wasm32")] +use dioxus_sdk::window::theme::{use_system_theme, Theme}; mod build; mod components; @@ -75,17 +75,17 @@ pub fn Playground( }); // // Handle events when code changes. - // let on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { - // // Update the project - // project.write().set_contents(new_code.clone()); - // spawn(async move { - // editor::monaco::set_markers(&[]); - - // if build.stage().is_finished() { - // attempt_hot_reload(hot_reload, &new_code); - // } - // }); - // }); + let on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { + // Update the project + project.write().set_contents(new_code.clone()); + spawn(async move { + editor::monaco::set_markers(&[]); + + if build.stage().is_finished() { + attempt_hot_reload(hot_reload, &new_code); + } + }); + }); // Handle setting diagnostics based on build state. use_effect(move || set_monaco_markers(build.diagnostics())); @@ -95,7 +95,7 @@ pub fn Playground( let system_theme = use_system_theme(); use_effect(move || { #[cfg(target_arch = "wasm32")] - editor::monaco::set_theme(system_theme().unwrap_or(SystemTheme::Light)); + editor::monaco::set_theme(system_theme().unwrap_or(Theme::Light)); }); // Handle starting a build. @@ -148,11 +148,11 @@ pub fn Playground( #[cfg(target_arch = "wasm32")] monaco::on_monaco_load( MONACO_FOLDER, - system_theme().unwrap_or(SystemTheme::Light), + system_theme().unwrap_or(Theme::Light), &project.read().contents(), hot_reload, monaco_ready, - on_model_changed, + on_model_changed.clone(), ); }, } From 83e95c44b0a3cd8df0b67f4d64556c1eefe9829e Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 23 Sep 2025 12:41:34 -0500 Subject: [PATCH 04/58] initially running --- Cargo.lock | 839 ++++++++++-------- Cargo.toml | 2 +- .../playground/server/src/build/builder.rs | 8 +- packages/playground/server/src/build/mod.rs | 2 +- .../server/template/snippets/Cargo.toml | 2 +- 5 files changed, 472 insertions(+), 381 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9551e63fc4..f748380c6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -68,12 +68,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -135,9 +129,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" @@ -209,15 +203,13 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6448dfb3960f0b038e88c781ead1e7eb7929dfc3a71a1336ec9086c00f6d1e75" +checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" dependencies = [ - "brotli", "compression-codecs", "compression-core", "futures-core", - "memchr", "pin-project-lite", "tokio", ] @@ -453,9 +445,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.3" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ "serde", ] @@ -556,7 +548,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cairo-sys-rs", "glib", "libc", @@ -577,11 +569,11 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.11" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d07aa9a93b00c76f71bc35d598bed923f6d4f3a9ca5c24b7737ae1a292841c0" +checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -609,10 +601,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.34" +version = "1.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -659,17 +652,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -701,9 +693,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.46" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" +checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" dependencies = [ "clap_builder", "clap_derive", @@ -711,9 +703,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.46" +version = "4.5.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" +checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" dependencies = [ "anstream", "anstyle", @@ -723,9 +715,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.45" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -763,7 +755,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block", "cocoa-foundation", "core-foundation 0.10.1", @@ -779,7 +771,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block", "core-foundation 0.10.1", "core-graphics-types", @@ -810,22 +802,19 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.28" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46cc6539bf1c592cff488b9f253b30bc0ec50d15407c2cf45e27bd8f308d5905" +checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" dependencies = [ "brotli", "compression-core", - "futures-core", - "memchr", - "pin-project-lite", ] [[package]] name = "compression-core" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2957e823c15bde7ecf1e8b64e537aa03a6be5fda0e2334e99887669e75b12e01" +checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" [[package]] name = "concurrent-queue" @@ -838,15 +827,15 @@ dependencies = [ [[package]] name = "console" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e09ced7ebbccb63b4c65413d821f2e00ce54c5ca4514ddc6b3c892fdbcbc69d" +checksum = "b430743a6eb14e9764d4260d4c0d8123087d504eeb9c48f2b2a5e810dd369df4" dependencies = [ "encode_unicode", "libc", "once_cell", "unicode-width", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -865,7 +854,16 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c02a1f46ffe1c6f05edf568a7d8e2ab477c75a6ec5f33d2b83ce54fc3f096ca" dependencies = [ - "const-serialize-macro", + "const-serialize-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", +] + +[[package]] +name = "const-serialize" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +dependencies = [ + "const-serialize-macro 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", "serde", ] @@ -880,6 +878,16 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "const-serialize-macro" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "const-str" version = "0.6.4" @@ -972,7 +980,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.10.1", "core-graphics-types", "foreign-types 0.5.0", @@ -985,7 +993,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.10.1", "libc", ] @@ -1177,9 +1185,9 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ "powerfmt", ] @@ -1268,7 +1276,7 @@ dependencies = [ "infer", "jni", "js-sys", - "manganis-core", + "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "ndk", "ndk-context", "ndk-sys", @@ -1441,7 +1449,7 @@ checksum = "64274704b6a8d018112473cdce0b3db1dcccfa79bde445223592fe4e396ff5ef" dependencies = [ "dioxus-core", "serde", - "subsecond-types", + "subsecond-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1580,12 +1588,13 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8cbe261980153962155a9d2353d8dad420f8c51229f988f09e338148ae59bc" +source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" dependencies = [ "cargo_metadata", + "manganis-core 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", "serde", "serde_json", + "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", ] [[package]] @@ -2192,7 +2201,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -2207,7 +2216,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2", "libc", "objc2", @@ -2230,7 +2239,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.8", + "libloading 0.8.9", ] [[package]] @@ -2410,12 +2419,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -2493,6 +2502,26 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "fdeflate" version = "0.3.7" @@ -2512,6 +2541,12 @@ dependencies = [ "rustc_version", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" + [[package]] name = "flate2" version = "1.1.2" @@ -2828,19 +2863,19 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.4.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix", + "windows-targets 0.52.6", ] [[package]] name = "getopts" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1" +checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ "unicode-width", ] @@ -2878,7 +2913,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] @@ -2935,7 +2970,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "futures-channel", "futures-core", "futures-executor", @@ -3175,6 +3210,12 @@ dependencies = [ "foldhash", ] +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + [[package]] name = "hashlink" version = "0.9.1" @@ -3377,9 +3418,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64", "bytes", @@ -3403,9 +3444,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3413,7 +3454,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.0", ] [[package]] @@ -3540,9 +3581,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", @@ -3550,8 +3591,9 @@ dependencies = [ "exr", "gif", "image-webp", + "moxcms", "num-traits", - "png", + "png 0.18.0", "qoi", "ravif", "rayon", @@ -3563,9 +3605,9 @@ dependencies = [ [[package]] name = "image-webp" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6970fe7a5300b4b42e62c52efa0187540a5bef546c60edaf554ef595d2e6f0b" +checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3" dependencies = [ "byteorder-lite", "quick-error", @@ -3598,12 +3640,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.0" +version = "2.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", ] [[package]] @@ -3663,7 +3705,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "libc", ] @@ -3766,17 +3808,11 @@ dependencies = [ "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" - [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" dependencies = [ "once_cell", "wasm-bindgen", @@ -3788,7 +3824,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "serde", "unicode-segmentation", ] @@ -3831,9 +3867,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lebe" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" +checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libappindicator" @@ -3861,9 +3897,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.175" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "libfuzzer-sys" @@ -3887,21 +3923,21 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.0", ] [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "libc", ] @@ -3942,15 +3978,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -3970,9 +4000,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "longest-increasing-subsequence" @@ -3991,9 +4021,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ea4e65087ff52f3862caff188d489f1fab49a0cb09e01b2e3f1a617b10aaed" +checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" dependencies = [ "hashbrown 0.15.5", ] @@ -4052,8 +4082,8 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "105544bc1d466decccab19427eddb801b6e575bb4907410eb4fed604ed78d358" dependencies = [ - "const-serialize", - "manganis-core", + "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "manganis-macro", ] @@ -4063,12 +4093,21 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71ef461824c58f3d260c1f548f7a8aee2e0b6b805a503d15f8535a3a6272d7" dependencies = [ - "const-serialize", + "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-cli-config", "dioxus-core-types", "serde", ] +[[package]] +name = "manganis-core" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +dependencies = [ + "const-serialize 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "serde", +] + [[package]] name = "manganis-macro" version = "0.7.0-rc.0" @@ -4077,7 +4116,7 @@ checksum = "06115a15f5d7bf6fcfee1b6979155cc51ab21ce7f06d907f6435d24175778f9e" dependencies = [ "dunce", "macro-string", - "manganis-core", + "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2", "quote", "syn 2.0.106", @@ -4124,11 +4163,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -4245,11 +4284,11 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "memfd" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" dependencies = [ - "rustix 0.38.44", + "rustix", ] [[package]] @@ -4330,6 +4369,16 @@ dependencies = [ "uuid", ] +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", +] + [[package]] name = "muda" version = "0.17.1" @@ -4346,7 +4395,7 @@ dependencies = [ "objc2-core-foundation", "objc2-foundation", "once_cell", - "png", + "png 0.17.16", "thiserror 2.0.16", "windows-sys 0.60.2", ] @@ -4391,7 +4440,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "jni-sys", "log", "ndk-sys", @@ -4427,7 +4476,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "cfg_aliases", "libc", @@ -4551,7 +4600,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.106", @@ -4582,7 +4631,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2", "objc2", "objc2-core-foundation", @@ -4595,7 +4644,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "dispatch2", "objc2", ] @@ -4606,7 +4655,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "objc2-core-foundation", ] @@ -4631,7 +4680,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2", "objc2", "objc2-core-foundation", @@ -4643,7 +4692,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -4655,7 +4704,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2", "objc2", "objc2-app-kit", @@ -4699,7 +4748,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "libc", "once_cell", "onig_sys", @@ -4721,7 +4770,7 @@ version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cfg-if", "foreign-types 0.3.2", "libc", @@ -4843,9 +4892,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", "thiserror 2.0.16", @@ -4854,9 +4903,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc" +checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" dependencies = [ "pest", "pest_generator", @@ -4864,9 +4913,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966" +checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" dependencies = [ "pest", "pest_meta", @@ -4877,9 +4926,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.1" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5" +checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" dependencies = [ "pest", "sha2", @@ -5075,9 +5124,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.4" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64", "indexmap", @@ -5099,6 +5148,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.4", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "pollster" version = "0.4.0" @@ -5126,9 +5188,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -5195,11 +5257,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.22.27", + "toml_edit 0.23.6", ] [[package]] @@ -5278,7 +5340,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "getopts", "memchr", "unicase", @@ -5290,7 +5352,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "getopts", "memchr", "pulldown-cmark-escape", @@ -5312,6 +5374,15 @@ dependencies = [ "pulldown-cmark 0.13.0", ] +[[package]] +name = "pxfm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" +dependencies = [ + "num-traits", +] + [[package]] name = "qoi" version = "0.4.1" @@ -5558,7 +5629,7 @@ version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", ] [[package]] @@ -5580,17 +5651,8 @@ checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.10", - "regex-syntax 0.8.6", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -5601,15 +5663,9 @@ checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.6", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.6" @@ -5742,7 +5798,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -5789,35 +5845,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.3", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys", + "windows-sys 0.61.0", ] [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "once_cell", "rustls-pki-types", @@ -5837,9 +5880,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" dependencies = [ "ring", "rustls-pki-types", @@ -5869,11 +5912,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.0", ] [[package]] @@ -5909,7 +5952,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -5918,9 +5961,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -5970,7 +6013,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "cssparser 0.34.0", "derive_more", "fxhash", @@ -5985,11 +6028,12 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] @@ -6003,10 +6047,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" dependencies = [ + "serde_core", "serde_derive", ] @@ -6021,11 +6066,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde_core" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.226" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" dependencies = [ "proc-macro2", "quote", @@ -6034,24 +6088,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa 1.0.15", "memchr", "ryu", "serde", + "serde_core", ] [[package]] name = "serde_path_to_error" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ "itoa 1.0.15", "serde", + "serde_core", ] [[package]] @@ -6488,11 +6544,11 @@ checksum = "b14ed4d86ab065ffbfdb994fd3e44daf5244b02cb643bd52949d74b703f36605" dependencies = [ "js-sys", "libc", - "libloading 0.8.8", + "libloading 0.8.9", "memfd", "memmap2", "serde", - "subsecond-types", + "subsecond-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 2.0.16", "wasm-bindgen", "wasm-bindgen-futures", @@ -6508,6 +6564,14 @@ dependencies = [ "serde", ] +[[package]] +name = "subsecond-types" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +dependencies = [ + "serde", +] + [[package]] name = "subtle" version = "2.6.1" @@ -6569,7 +6633,7 @@ dependencies = [ "once_cell", "onig", "plist", - "regex-syntax 0.8.6", + "regex-syntax", "serde", "serde_derive", "serde_json", @@ -6594,7 +6658,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -6624,11 +6688,11 @@ dependencies = [ [[package]] name = "tao" -version = "0.34.2" +version = "0.34.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4daa814018fecdfb977b59a094df4bd43b42e8e21f88fddfc05807e6f46efaaf" +checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "block2", "core-foundation 0.10.1", "core-graphics", @@ -6658,7 +6722,7 @@ dependencies = [ "unicode-segmentation", "url", "windows", - "windows-core", + "windows-core 0.61.2", "windows-version", "x11-dl", ] @@ -6682,15 +6746,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.21.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", "getrandom 0.3.3", "once_cell", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix", + "windows-sys 0.61.0", ] [[package]] @@ -6770,20 +6834,23 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" dependencies = [ + "fax", "flate2", - "jpeg-decoder", + "half", + "quick-error", "weezl", + "zune-jpeg", ] [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa 1.0.15", @@ -6796,15 +6863,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -6864,9 +6931,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" dependencies = [ "rustls", "tokio", @@ -6938,7 +7005,7 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_edit 0.19.15", ] @@ -6950,7 +7017,7 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_edit 0.22.27", ] @@ -6963,6 +7030,15 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.19.15" @@ -6972,7 +7048,7 @@ dependencies = [ "indexmap", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -6983,7 +7059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ "indexmap", - "toml_datetime", + "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -6996,11 +7072,32 @@ dependencies = [ "indexmap", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow 0.7.13", ] +[[package]] +name = "toml_edit" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +dependencies = [ + "indexmap", + "toml_datetime 0.7.2", + "toml_parser", + "winnow 0.7.13", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ + "winnow 0.7.13", +] + [[package]] name = "toml_write" version = "0.1.2" @@ -7045,7 +7142,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "async-compression", - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-core", "futures-util", @@ -7071,7 +7168,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "bytes", "futures-core", "futures-util", @@ -7149,13 +7246,13 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "once_cell", - "regex", + "regex-automata", "sharded-slab", "thread_local", "tracing", @@ -7189,7 +7286,7 @@ dependencies = [ "objc2-core-graphics", "objc2-foundation", "once_cell", - "png", + "png 0.17.16", "thiserror 2.0.16", "windows-sys 0.59.0", ] @@ -7267,9 +7364,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-segmentation" @@ -7356,9 +7453,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ "getrandom 0.3.3", "js-sys", @@ -7451,18 +7548,27 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" dependencies = [ - "wit-bindgen-rt", + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" dependencies = [ "cfg-if", "once_cell", @@ -7470,13 +7576,14 @@ dependencies = [ "serde", "serde_json", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" dependencies = [ "bumpalo", "log", @@ -7488,9 +7595,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67" dependencies = [ "cfg-if", "js-sys", @@ -7501,9 +7608,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7511,9 +7618,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" dependencies = [ "proc-macro2", "quote", @@ -7524,9 +7631,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" dependencies = [ "unicode-ident", ] @@ -7552,7 +7659,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 1.0.8", + "rustix", "scoped-tls", "smallvec", "wayland-sys", @@ -7564,8 +7671,8 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.3", - "rustix 1.0.8", + "bitflags 2.9.4", + "rustix", "wayland-backend", "wayland-scanner", ] @@ -7576,7 +7683,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.3", + "bitflags 2.9.4", "wayland-backend", "wayland-client", "wayland-scanner", @@ -7606,9 +7713,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" dependencies = [ "js-sys", "wasm-bindgen", @@ -7693,7 +7800,7 @@ dependencies = [ "webview2-com-macros", "webview2-com-sys", "windows", - "windows-core", + "windows-core 0.61.2", "windows-implement", "windows-interface", ] @@ -7717,7 +7824,7 @@ checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" dependencies = [ "thiserror 2.0.16", "windows", - "windows-core", + "windows-core 0.61.2", ] [[package]] @@ -7744,11 +7851,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.0", ] [[package]] @@ -7764,9 +7871,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -7776,7 +7883,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", ] [[package]] @@ -7787,9 +7894,22 @@ checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] @@ -7798,8 +7918,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", "windows-threading", ] @@ -7831,14 +7951,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", ] [[package]] @@ -7847,9 +7973,9 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", ] [[package]] @@ -7858,7 +7984,16 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -7867,7 +8002,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", ] [[package]] @@ -7906,6 +8050,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -7921,21 +8074,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -7958,7 +8096,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -7975,16 +8113,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] name = "windows-version" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04a5c6627e310a23ad2358483286c7df260c964eb2d003d8efd6d0f4e79265c" +checksum = "69e061eb0a22b4a1d778ad70f7575ec7845490abb35b08fa320df7895882cacb" dependencies = [ - "windows-link", + "windows-link 0.2.0", ] [[package]] @@ -7993,12 +8131,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -8017,12 +8149,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -8041,12 +8167,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -8077,12 +8197,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -8101,12 +8215,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -8125,12 +8233,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -8149,12 +8251,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -8186,13 +8282,10 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "writeable" @@ -8238,7 +8331,7 @@ dependencies = [ "webkit2gtk-sys", "webview2-com", "windows", - "windows-core", + "windows-core 0.61.2", "windows-version", ] @@ -8265,20 +8358,20 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "gethostname", - "rustix 0.38.44", + "rustix", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xkeysym" @@ -8339,9 +8432,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a073be99ace1adc48af593701c8015cd9817df372e14a1a6b0ee8f8bf043be" +checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" dependencies = [ "async-broadcast", "async-recursion", @@ -8367,11 +8460,11 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e80cd713a45a49859dcb648053f63265f4f2851b6420d47a958e5697c68b131" +checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.106", @@ -8394,18 +8487,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", @@ -8489,9 +8582,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1f7e205ce79eb2da3cd71c5f55f3589785cb7c79f6a03d1c8d1491bda5d089" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" dependencies = [ "zune-core", ] @@ -8517,7 +8610,7 @@ version = "5.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", "syn 2.0.106", diff --git a/Cargo.toml b/Cargo.toml index 5392efb342..d27fc7f959 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,7 +79,7 @@ dioxus-rsx = "0.7.0-rc.0" dioxus-html = { version = "0.7.0-rc.0", default-features = false } dioxus-rsx-rosetta = "0.7.0-rc.0" dioxus-autofmt = "0.7.0-rc.0" -dioxus-dx-wire-format = "0.7.0-rc.0" +dioxus-dx-wire-format = { git = "https://github.com/DioxusLabs/dioxus" } dioxus-logger = "0.7.0-rc.0" # 3rd-party dioxus diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index c1939485d3..30f17b180b 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -99,7 +99,6 @@ async fn build( setup_template(&template_path, &request).await?; dx_build(&template_path, &request).await?; - tracing::trace!("Noving build from {template_path:?} to {built_path:?}"); move_to_built(&template_path, &built_path, &request).await?; Ok(()) @@ -197,11 +196,9 @@ async fn dx_build(template_path: &PathBuf, request: &BuildRequest) -> Result<(), fn process_dx_message(request: &BuildRequest, message: String) { // We parse the tracing json log and if it contains a json field, we parse that as StructuredOutput. let result = serde_json::from_str::(&message) - .ok() - .and_then(|v| v.json) - .and_then(|json| serde_json::from_str::(&json).ok()); + .and_then(|m| serde_json::from_str::(&m.json)); - let Some(output) = result else { + let Ok(output) = result else { return; }; @@ -251,6 +248,7 @@ async fn move_to_built( // Delete the built project in the target directory to prevent a storage leak. // We use `spawn_blocking` to batch call `std::fs` as recommended by Tokio. tokio::task::spawn_blocking::<_, Result<(), BuildError>>(move || { + _ = std::fs::create_dir_all(&built_path); // Rename to be the build id let built_project = debug_web.join(&id_string); std::fs::rename(&public_folder, &built_project)?; diff --git a/packages/playground/server/src/build/mod.rs b/packages/playground/server/src/build/mod.rs index cc04a14223..fdda8914e1 100644 --- a/packages/playground/server/src/build/mod.rs +++ b/packages/playground/server/src/build/mod.rs @@ -35,7 +35,7 @@ pub enum BuildMessage { /// The DX CLI serves parseable JSON output with the regular tracing message and a parseable "json" field. #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct CliMessage { - json: Option, + json: String, } /// Build failed to complete. diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index b72469b69d..7612819327 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -7,7 +7,7 @@ version = "0.1.0" edition = "2021" [dependencies] -dioxus = { version= "0.6", features = ["web", "router"] } +dioxus = { version= "0.7.0-rc.0", features = ["web", "router"] } [profile.dev] opt-level = 1 From d06b3853cff5f5cc331e83cc71d98b18dc7dea8d Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 23 Sep 2025 12:48:15 -0500 Subject: [PATCH 05/58] don't panic every time we edit the code --- packages/playground/playground/src/editor/monaco.rs | 5 ++--- packages/playground/playground/src/lib.rs | 6 ++++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index d22d0bc9b3..69424fc2d2 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -60,7 +60,7 @@ pub fn on_monaco_load( contents: &str, mut hot_reload: HotReload, mut monaco_ready: Signal, - mut on_model_changed: UseDebounce, + mut on_model_changed: Callback, ) { let on_ready_callback = Closure::new(move || monaco_ready.set(true)); let monaco_prefix = monaco_vs_prefix(folder); @@ -74,8 +74,7 @@ pub fn on_monaco_load( hot_reload.set_starting_code(contents); - let model_change_callback = - Closure::new(move |new_code: String| on_model_changed.action(new_code)); + let model_change_callback = Closure::new(move |new_code: String| on_model_changed(new_code)); register_model_change_event(&model_change_callback); on_ready_callback.forget(); diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index cf4933ef57..971a8faf50 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -75,7 +75,7 @@ pub fn Playground( }); // // Handle events when code changes. - let on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { + let mut on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { // Update the project project.write().set_contents(new_code.clone()); spawn(async move { @@ -87,6 +87,8 @@ pub fn Playground( }); }); + let mut on_model_changed = use_callback(move |args| on_model_changed.action(args)); + // Handle setting diagnostics based on build state. use_effect(move || set_monaco_markers(build.diagnostics())); @@ -152,7 +154,7 @@ pub fn Playground( &project.read().contents(), hot_reload, monaco_ready, - on_model_changed.clone(), + on_model_changed, ); }, } From 28dc156472a46918817b1419790f7d1aec367132 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 23 Sep 2025 13:39:10 -0500 Subject: [PATCH 06/58] use tower instead or rebuilding our own file server --- Cargo.lock | 44 +++++++++++++++-- packages/playground/server/Cargo.toml | 2 + packages/playground/server/src/serve.rs | 63 +++++++------------------ 3 files changed, 59 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f748380c6d..1c9c127f1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1997,7 +1997,7 @@ dependencies = [ "hyper-util", "inventory", "parking_lot", - "pin-project", + "pin-project 1.1.10", "serde", "server_fn", "subsecond", @@ -3040,7 +3040,7 @@ dependencies = [ "gloo-utils", "http", "js-sys", - "pin-project", + "pin-project 1.1.10", "serde", "serde_json", "thiserror 1.0.69", @@ -5084,13 +5084,33 @@ dependencies = [ "siphasher 1.0.1", ] +[[package]] +name = "pin-project" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef0f924a5ee7ea9cbcea77529dba45f8a9ba9f622419fe3386ca581a3ae9d5a" +dependencies = [ + "pin-project-internal 0.4.30", +] + [[package]] name = "pin-project" version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ - "pin-project-internal", + "pin-project-internal 1.1.10", +] + +[[package]] +name = "pin-project-internal" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "851c8d0ce9bebe43790dedfc86614c23494ac9f423dd618d3a61fc693eafe61e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -6174,6 +6194,8 @@ dependencies = [ "tokio-util", "tower 0.4.13", "tower-http 0.5.2", + "tower-util", + "tracing", "uuid", ] @@ -7202,6 +7224,18 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +[[package]] +name = "tower-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1093c19826d33807c72511e68f73b4a0469a3f22c2bd5f7d5212178b4b89674" +dependencies = [ + "futures-core", + "futures-util", + "pin-project 0.4.30", + "tower-service", +] + [[package]] name = "tracing" version = "0.1.41" @@ -7240,7 +7274,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project", + "pin-project 1.1.10", "tracing", ] @@ -7518,7 +7552,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64f68998838dab65727c9b30465595c6f7c953313559371ca8bf31759b3680ad" dependencies = [ - "pin-project", + "pin-project 1.1.10", "tracing", "warnings-macro", ] diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index f5ea9c420e..bf8e38b212 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -27,3 +27,5 @@ thiserror = { workspace = true } dioxus = { workspace = true, features = ["web"] } example-projects = { workspace = true } +tracing = "0.1.41" +tower-util = "0.3.1" diff --git a/packages/playground/server/src/serve.rs b/packages/playground/server/src/serve.rs index 57c3fba3a4..9ee2e47517 100644 --- a/packages/playground/server/src/serve.rs +++ b/packages/playground/server/src/serve.rs @@ -7,6 +7,8 @@ use axum::{ use dioxus_logger::tracing::warn; use std::path::PathBuf; use tokio_util::io::ReaderStream; +use tower_http::services::{ServeDir, ServeFile}; +use tower_util::ServiceExt; use uuid::Uuid; use crate::app::AppState; @@ -16,29 +18,25 @@ use crate::app::AppState; pub async fn serve_built_index( State(state): State, Path(build_id): Path, + request: axum::extract::Request, ) -> impl IntoResponse { let path = state.env.built_path.join(build_id.to_string()); let index_path = path.join("index.html"); - let file = match tokio::fs::File::open(index_path.clone()).await { - Ok(f) => f, - Err(e) => { - warn!(err = ?e, path = ?index_path, "failed to read built project:"); - return Err((StatusCode::NOT_FOUND, "not found")); - } - }; - let stream = ReaderStream::new(file); - let body = Body::from_stream(stream); - - let headers = [(header::CONTENT_TYPE, "text/html")]; - - Ok((headers, body)) + tower_http::services::ServeFile::new(index_path) + .oneshot(request) + .await + .map_err(|e| { + warn!(err = ?e, build_id = ?build_id, "failed to serve built project file:"); + (StatusCode::NOT_FOUND, "not found") + }) } pub async fn serve_other_built( State(state): State, Path((build_id, file_path)): Path<(Uuid, PathBuf)>, + request: axum::extract::Request, ) -> impl IntoResponse { let path = state .env @@ -46,36 +44,11 @@ pub async fn serve_other_built( .join(build_id.to_string()) .join(file_path); - let file = match tokio::fs::File::open(path.clone()).await { - Ok(f) => f, - Err(e) => { - warn!(err = ?e, path = ?path, "failed to read built project:"); - return Err((StatusCode::NOT_FOUND, "read failure")); - } - }; - - let Some(file_ext) = path.extension() else { - warn!(build_id = ?build_id, path = ?path, "failed to get file extension"); - return Err((StatusCode::INTERNAL_SERVER_ERROR, "read failure")); - }; - - let content_type = match file_ext.to_str() { - Some("wasm") => "application/wasm", - Some("js") => "application/javascript", - Some(_) => { - warn!(build_id = ?build_id, path = ?path, "project tried accessing denied file"); - return Err((StatusCode::NOT_FOUND, "not found")); - } - None => { - warn!(build_id = ?build_id, path = ?path, "failed to get file extension"); - return Err((StatusCode::INTERNAL_SERVER_ERROR, "read failure")); - } - }; - - let stream = ReaderStream::new(file); - let body = Body::from_stream(stream); - - let headers = [(header::CONTENT_TYPE, content_type)]; - - Ok((headers, body)) + tower_http::services::ServeFile::new(path) + .oneshot(request) + .await + .map_err(|e| { + warn!(err = ?e, build_id = ?build_id, "failed to serve built project file:"); + (StatusCode::NOT_FOUND, "not found") + }) } From ba85fd26faa7acf99618a99e057c4ffe28de1ed2 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 08:49:35 -0500 Subject: [PATCH 07/58] fix hot reloading the prebuilt examples --- Cargo.lock | 337 ++++++++++++++++-- packages/playground/playground/src/build.rs | 10 +- packages/playground/playground/src/lib.rs | 4 +- packages/playground/server/Cargo.toml | 7 +- .../playground/server/src/build/builder.rs | 37 +- .../playground/server/src/build/watcher.rs | 2 + packages/playground/server/src/main.rs | 49 ++- 7 files changed, 389 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1c9c127f1c..c2c05aca8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -225,6 +225,28 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -314,15 +336,42 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "axum" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +dependencies = [ + "async-trait", + "axum-core 0.4.5", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa 1.0.15", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower 0.5.2", + "tower-layer", + "tower-service", +] + [[package]] name = "axum" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" dependencies = [ - "axum-core", + "axum-core 0.5.2", "axum-macros", - "base64", + "base64 0.22.1", "bytes", "form_urlencoded", "futures-util", @@ -332,7 +381,7 @@ dependencies = [ "hyper", "hyper-util", "itoa 1.0.15", - "matchit", + "matchit 0.8.4", "memchr", "mime", "multer", @@ -359,11 +408,31 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f08a543641554404b42acd0d2494df12ca2be034d7b8ee4dbbf7446f940a2ef" dependencies = [ - "axum", + "axum 0.8.4", "client-ip", "serde", ] +[[package]] +name = "axum-core" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "axum-core" version = "0.5.2" @@ -416,6 +485,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -838,6 +913,45 @@ dependencies = [ "windows-sys 0.61.0", ] +[[package]] +name = "console-api" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857" +dependencies = [ + "futures-core", + "prost", + "prost-types", + "tonic", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime", + "hyper-util", + "prost", + "prost-types", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic", + "tracing", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -1375,7 +1489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8190b532291840504195a5aeb9125f53df2001006acdcd876929d64ecdac1fc8" dependencies = [ "async-trait", - "base64", + "base64 0.22.1", "cocoa", "core-foundation 0.10.1", "dioxus-asset-resolver", @@ -1532,7 +1646,7 @@ dependencies = [ "askama_escape 0.10.3", "async-recursion", "automod", - "axum", + "axum 0.8.4", "chrono", "dioxus", "dioxus-cli-config", @@ -1603,7 +1717,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "819981e8aa811d9b81ac3135a8a74db2f1fa7510473c3251f98eceb2c710632e" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "ciborium", "dioxus-core", @@ -1647,7 +1761,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2f266ad9e20be14b8899f2133dd942131f03e6749650e65e2aaec2c7f8a4bc1" dependencies = [ - "base64", + "base64 0.22.1", "ciborium", "dioxus-core", "serde", @@ -1760,7 +1874,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90ea4ac81b0c239f00c70a06d1433135babca3412817d4c21a1a188964e5a7f" dependencies = [ - "axum", + "axum 0.8.4", "dioxus-cli-config", "dioxus-core", "dioxus-devtools", @@ -1799,7 +1913,7 @@ dependencies = [ name = "dioxus-playground" version = "0.1.0" dependencies = [ - "base64", + "base64 0.22.1", "dioxus", "dioxus-autofmt", "dioxus-core", @@ -1969,8 +2083,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1116ed485980f0df75d9251dd216e325e059d71fe1ef823ee967105aa4d4be48" dependencies = [ "async-trait", - "axum", - "base64", + "axum 0.8.4", + "base64 0.22.1", "bytes", "ciborium", "dashmap", @@ -2135,7 +2249,7 @@ dependencies = [ "askama_escape 0.10.3", "async-recursion", "automod", - "axum", + "axum 0.8.4", "chrono", "dioxus", "dioxus-docs-03", @@ -3164,7 +3278,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.11.4", "slab", "tokio", "tokio-util", @@ -3190,6 +3304,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -3225,6 +3345,19 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64 0.21.7", + "byteorder", + "flate2", + "nom", + "num-traits", +] + [[package]] name = "heapless" version = "0.7.17" @@ -3361,6 +3494,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" + [[package]] name = "hyper" version = "1.7.0" @@ -3400,6 +3539,19 @@ dependencies = [ "tower-service", ] +[[package]] +name = "hyper-timeout" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -3422,7 +3574,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -3434,7 +3586,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.0", "system-configuration", "tokio", "tower-service", @@ -3638,6 +3790,16 @@ dependencies = [ "quote", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.11.4" @@ -3849,7 +4011,7 @@ checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" dependencies = [ "cssparser 0.29.6", "html5ever 0.29.1", - "indexmap", + "indexmap 2.11.4", "selectors 0.24.0", ] @@ -4176,6 +4338,12 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "matchit" version = "0.8.4" @@ -4356,7 +4524,7 @@ dependencies = [ name = "model" version = "0.1.0" dependencies = [ - "axum", + "axum 0.8.4", "dioxus-document", "dioxus-dx-wire-format", "dioxus-logger", @@ -4518,6 +4686,15 @@ dependencies = [ "walkdir", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -5148,8 +5325,8 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ - "base64", - "indexmap", + "base64 0.22.1", + "indexmap 2.11.4", "quick-xml 0.38.3", "serde", "time", @@ -5354,6 +5531,38 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "prost" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "prost-types" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +dependencies = [ + "prost", +] + [[package]] name = "pulldown-cmark" version = "0.9.6" @@ -5698,7 +5907,7 @@ version = "0.12.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "encoding_rs", "futures-core", @@ -6177,8 +6386,9 @@ dependencies = [ name = "server" version = "0.1.0" dependencies = [ - "axum", + "axum 0.8.4", "axum-client-ip", + "console-subscriber", "dioxus", "dioxus-dx-wire-format", "dioxus-logger", @@ -6196,6 +6406,7 @@ dependencies = [ "tower-http 0.5.2", "tower-util", "tracing", + "tracing-subscriber", "uuid", ] @@ -6205,8 +6416,8 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" dependencies = [ - "axum", - "base64", + "axum 0.8.4", + "base64 0.22.1", "bytes", "const-str", "const_format", @@ -6440,6 +6651,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "socket2" version = "0.6.0" @@ -6924,7 +7145,7 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "slab", - "socket2", + "socket2 0.6.0", "tokio-macros", "tracing", "windows-sys 0.59.0", @@ -7067,7 +7288,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap", + "indexmap 2.11.4", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -7080,7 +7301,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap", + "indexmap 2.11.4", "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -7091,7 +7312,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap", + "indexmap 2.11.4", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -7105,7 +7326,7 @@ version = "0.23.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" dependencies = [ - "indexmap", + "indexmap 2.11.4", "toml_datetime 0.7.2", "toml_parser", "winnow 0.7.13", @@ -7126,6 +7347,36 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "tonic" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" +dependencies = [ + "async-stream", + "async-trait", + "axum 0.7.9", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project 1.1.10", + "prost", + "socket2 0.5.10", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" @@ -7133,7 +7384,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project 1.1.10", "pin-project-lite", + "rand 0.8.5", + "slab", "tokio", "tokio-util", "tower-layer", @@ -7266,6 +7522,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ "once_cell", + "valuable", ] [[package]] @@ -7278,6 +7535,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.20" @@ -7285,12 +7553,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", + "nu-ansi-term", "once_cell", "regex-automata", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", + "tracing-log", ] [[package]] @@ -7509,6 +7780,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vcpkg" version = "0.2.15" @@ -8333,7 +8610,7 @@ version = "0.52.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12a714d9ba7075aae04a6e50229d6109e3d584774b99a6a8c60de1698ca111b9" dependencies = [ - "base64", + "base64 0.22.1", "block2", "cookie", "crossbeam-channel", diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index aaee788927..126f3c3b02 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -1,6 +1,6 @@ use crate::ws; use dioxus::prelude::*; -use model::{AppError, CargoDiagnostic, SocketMessage}; +use model::{AppError, CargoDiagnostic, Project, SocketMessage}; use uuid::Uuid; #[derive(Debug, Clone, PartialEq)] @@ -63,9 +63,13 @@ pub(crate) struct BuildState { } impl BuildState { - pub fn new() -> Self { + pub fn new(project: &Project) -> Self { Self { - stage: Signal::new(BuildStage::NotStarted), + stage: Signal::new(if project.prebuilt { + BuildStage::Finished(Ok(project.id())) + } else { + BuildStage::NotStarted + }), queue_position: Signal::new(None), diagnostics: Signal::new(Vec::new()), } diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 971a8faf50..098e70edc4 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -39,7 +39,6 @@ pub fn Playground( share_code: ReadOnlySignal>, class: Option, ) -> Element { - let mut build = use_context_provider(BuildState::new); let mut hot_reload = use_context_provider(HotReload::new); let api_client = use_context_provider(|| Signal::new(ApiClient::new(urls.server))); let mut errors = use_context_provider(Errors::new); @@ -50,6 +49,7 @@ pub fn Playground( // Default to the welcome project. // Project dirty determines whether the Rust-project is synced with the project in the editor. let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); + let mut build = use_context_provider(|| BuildState::new(&project.read())); let mut project_dirty = use_signal(|| false); use_effect(move || { if project_dirty() && monaco_ready() { @@ -74,7 +74,7 @@ pub fn Playground( } }); - // // Handle events when code changes. + // Handle events when code changes. let mut on_model_changed = use_debounce(Duration::from_millis(250), move |new_code: String| { // Update the project project.write().set_contents(new_code.clone()); diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index bf8e38b212..27ce454ef6 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "server" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] model = { workspace = true, features = ["server"] } @@ -21,6 +21,7 @@ tokio-util = { version = "0.7.11", features = ["futures-util"] } tower-http = { version = "0.5.2", features = ["compression-br", "cors", "fs"] } tower = { version = "0.4.13", features = ["buffer", "limit"] } reqwest = { workspace = true, features = ["json"] } +console-subscriber = { version = "0.4.1", optional = true } thiserror = { workspace = true } @@ -29,3 +30,7 @@ dioxus = { workspace = true, features = ["web"] } example-projects = { workspace = true } tracing = "0.1.41" tower-util = "0.3.1" +tracing-subscriber = "0.3.20" + +[features] +tracing = ["tokio/tracing", "dep:console-subscriber"] diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 30f17b180b..00eb088426 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -6,10 +6,11 @@ use dioxus_logger::tracing; use dioxus_logger::tracing::debug; use fs_extra::dir::CopyOptions; use model::{BuildStage, CargoDiagnostic}; +use std::future::pending; use std::path::{Path, PathBuf}; use std::process::Stdio; -use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicBool, Ordering}; use tokio::io::{AsyncBufReadExt as _, BufReader}; use tokio::process::Command; use tokio::task::JoinHandle; @@ -24,7 +25,7 @@ pub struct Builder { built_path: PathBuf, is_building: Arc, current_build: Option, - task: JoinHandle>, + task: Option>>, } impl Builder { @@ -34,7 +35,7 @@ impl Builder { built_path: env.built_path, is_building, current_build: None, - task: tokio::spawn(std::future::pending()), + task: None, } } @@ -45,17 +46,18 @@ impl Builder { self.stop_current(); self.is_building.store(true, Ordering::SeqCst); self.current_build = Some(request.clone()); - self.task = tokio::spawn(build( + self.task = Some(tokio::spawn(build( self.template_path.clone(), self.built_path.clone(), request, - )); + ))); } /// Stop the current build. pub fn stop_current(&mut self) { - self.task.abort(); - self.task = tokio::spawn(std::future::pending()); + if let Some(task) = self.task.take() { + task.abort(); + } self.current_build = None; self.is_building.store(false, Ordering::SeqCst); } @@ -63,15 +65,16 @@ impl Builder { /// Wait for the current build to finish. pub async fn finished(&mut self) -> Result { // Ensure we don't poll a completed task. - if self.task.is_finished() { - self.stop_current(); + if let Some(task) = &mut self.task { + if task.is_finished() { + self.stop_current(); + } else { + // Make progress on the build task. + task.await??; + return self.current_build.take().ok_or(BuildError::NotStarted); + } } - - // Make progress on the build task. - let task = &mut self.task; - task.await??; - - self.current_build.take().ok_or(BuildError::NotStarted) + pending().await } /// Check if the builder has an ongoing build. @@ -168,6 +171,10 @@ async fn dx_build(template_path: &PathBuf, request: &BuildRequest) -> Result<(), } // Wait for the DX process to exit. status = child.wait() => { + while let Ok(Some(line)) = stdout_reader.next_line().await { + logs.push(line.clone()); + process_dx_message(request, line); + } // Check if the build was successful. let exit_code = status.map(|c| c.code()); if let Ok(Some(code)) = exit_code { diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index dbad085ee8..d69772652a 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -29,6 +29,7 @@ pub fn start_build_watcher( select! { // Handle incoming build commands. Some(command) = rx.recv() => { + tracing::info!("got command: {command:?}"); match command { BuildCommand::Start { request } => start_build(&mut builder, &mut pending_builds, request), BuildCommand::Stop { id } => stop_build(&mut builder, &mut pending_builds, id), @@ -67,6 +68,7 @@ fn start_build( /// - Iterate through queue looking for a matching id. /// If matching id found, update queue positions *behind* matching queue and remove matched item. fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque, id: Uuid) { + tracing::info!("stopping build {id:?}"); // Check if the ongoing build is the cancelled build. let current_build_id = builder.current_build().map(|b| b.id); if let Some(current_build_id) = current_build_id { diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 0a94870292..b407be4c3d 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -1,19 +1,19 @@ use app::AppState; use axum::{ + BoxError, Router, error_handling::HandleErrorLayer, extract::{Request, State}, http::StatusCode, middleware::{self, Next}, response::{Redirect, Response}, routing::{get, post}, - BoxError, Router, }; use axum_client_ip::ClientIpSource; -use dioxus_logger::tracing::{error, info, warn, Level}; +use dioxus_logger::tracing::{Level, error, info, warn}; use share::{get_shared_project, share_project}; use std::{io, net::SocketAddr, sync::atomic::Ordering, time::Duration}; use tokio::{net::TcpListener, select, time::Instant}; -use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder}; +use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer}; use tower_http::{compression::CompressionLayer, cors::CorsLayer}; mod app; @@ -24,13 +24,36 @@ mod ws; /// Rate limiter configuration. /// How many requests each user should get within a time period. -const REQUESTS_PER_INTERVAL: u64 = 30; +const REQUESTS_PER_INTERVAL: u64 = 60; /// The period of time after the request limit resets. const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); +/// How many websocket requests each user should get within a time period. +const WS_REQUESTS_PER_INTERVAL: u64 = 3; +/// The period of time after the request limit resets. +const WS_RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); #[tokio::main] async fn main() { - dioxus_logger::init(Level::INFO).expect("failed to init logger"); + #[cfg(feature = "tracing")] + { + use tracing_subscriber::prelude::*; + + let console_layer = console_subscriber::spawn(); + use tracing_subscriber::prelude::*; + use tracing_subscriber::{EnvFilter, fmt}; + + let fmt_layer = fmt::layer(); + let filter_layer = EnvFilter::try_from_default_env() + .or_else(|_| EnvFilter::try_new("info")) + .unwrap(); + + tracing_subscriber::registry() + .with(console_layer) + .with(filter_layer) + .with(fmt_layer) + .init(); + } + _ = dioxus_logger::init(Level::INFO); let state = AppState::new().await; let port = state.env.port; @@ -50,7 +73,21 @@ async fn main() { .route("/{:id}", get(get_shared_project)); let app = Router::new() - .route("/ws", get(ws::ws_handler)) + .nest( + "/ws", + Router::new().route("/", get(ws::ws_handler)).layer( + ServiceBuilder::new() + .layer(HandleErrorLayer::new(|error: BoxError| async move { + error!(?error, "unhandled server error"); + (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error") + })) + .layer(BufferLayer::new(1024)) + .layer(RateLimitLayer::new( + REQUESTS_PER_INTERVAL, + RATE_LIMIT_INTERVAL, + )), + ), + ) .nest("/built/{:build_id}", built_router) .nest("/shared", shared_router) .route( From 36ecd374c0bfcb36d5dcd93677cb94ce43aa8238 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 09:03:26 -0500 Subject: [PATCH 08/58] command enter shortcut --- .../playground/src/editor/monaco.js | 8 ++++- .../playground/src/editor/monaco.rs | 16 ++++----- packages/playground/playground/src/lib.rs | 35 +++++++++---------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/packages/playground/playground/src/editor/monaco.js b/packages/playground/playground/src/editor/monaco.js index 56cb26e077..32349ed985 100644 --- a/packages/playground/playground/src/editor/monaco.js +++ b/packages/playground/playground/src/editor/monaco.js @@ -5,8 +5,9 @@ export function initMonaco( vsPathPrefix, elementId, initialTheme, - initialSnippet, + initialSnippet, onReadyCallback, + onBuildCallback, ) { require.config({ paths: { vs: vsPathPrefix } }); @@ -87,6 +88,11 @@ export function initMonaco( "semanticHighlighting.enabled": true, }); + // Super+Enter for Mac, Ctrl+Enter for others. + editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => { + onBuildCallback(); + }); + monacoEditor = editor; currentMonacoModel = model; }); diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index 69424fc2d2..22cc678257 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -1,13 +1,10 @@ use crate::hotreload::HotReload; use dioxus::prelude::*; -use dioxus_sdk::time::UseDebounce; +use dioxus_sdk::window::theme::Theme; use model::{CargoDiagnostic, CargoLevel}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -#[cfg(target_arch = "wasm32")] -use dioxus_sdk::window::theme::Theme; - /// Get the path prefix for the `/vs` folder inside the Monaco folder. pub fn monaco_vs_prefix(folder: Asset) -> String { let monaco_vs_prefix = format!("{}/vs", folder); @@ -53,7 +50,6 @@ pub fn set_monaco_markers(diagnostics: Signal>) { } /// Initialize Monaco once the loader script loads. -#[cfg(target_arch = "wasm32")] pub fn on_monaco_load( folder: Asset, system_theme: Theme, @@ -61,15 +57,18 @@ pub fn on_monaco_load( mut hot_reload: HotReload, mut monaco_ready: Signal, mut on_model_changed: Callback, + mut onbuild_callback: Callback<()>, ) { let on_ready_callback = Closure::new(move || monaco_ready.set(true)); let monaco_prefix = monaco_vs_prefix(folder); + let onbuild_callback = Closure::new(move || onbuild_callback.call(())); init( &monaco_prefix, super::EDITOR_ELEMENT_ID, system_theme, contents, &on_ready_callback, + &onbuild_callback, ); hot_reload.set_starting_code(contents); @@ -79,6 +78,7 @@ pub fn on_monaco_load( on_ready_callback.forget(); model_change_callback.forget(); + onbuild_callback.forget(); } #[derive(Serialize, Deserialize, Clone)] @@ -122,6 +122,7 @@ extern "C" { initial_theme: &str, initial_snippet: &str, on_ready_callback: &Closure, + on_build_callback: &Closure, ); #[wasm_bindgen(js_name = getCurrentModelValue)] @@ -146,13 +147,13 @@ extern "C" { fn register_model_change_event(callback: &Closure); } -#[cfg(target_arch = "wasm32")] pub fn init( vs_path_prefix: &str, element_id: &str, initial_theme: Theme, initial_snippet: &str, on_ready_callback: &Closure, + on_build_callback: &Closure, ) { let theme = system_theme_to_string(initial_theme); init_monaco( @@ -161,11 +162,11 @@ pub fn init( &theme, initial_snippet, on_ready_callback, + on_build_callback, ); register_paste_as_rsx_action(); } -#[cfg(target_arch = "wasm32")] pub fn set_theme(theme: Theme) { let theme = system_theme_to_string(theme); set_monaco_theme(&theme); @@ -182,7 +183,6 @@ fn register_paste_as_rsx_action() { callback.forget(); } -#[cfg(target_arch = "wasm32")] fn system_theme_to_string(theme: Theme) -> String { match theme { Theme::Light => "dx-vs", diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 098e70edc4..938dd5376a 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -9,7 +9,6 @@ use hotreload::{attempt_hot_reload, HotReload}; use model::{api::ApiClient, AppError, Project, SocketError}; use std::time::Duration; -#[cfg(target_arch = "wasm32")] use dioxus_sdk::window::theme::{use_system_theme, Theme}; mod build; @@ -87,35 +86,35 @@ pub fn Playground( }); }); - let mut on_model_changed = use_callback(move |args| on_model_changed.action(args)); + let on_model_changed = use_callback(move |args| on_model_changed.action(args)); // Handle setting diagnostics based on build state. use_effect(move || set_monaco_markers(build.diagnostics())); // Themes - #[cfg(target_arch = "wasm32")] let system_theme = use_system_theme(); use_effect(move || { - #[cfg(target_arch = "wasm32")] editor::monaco::set_theme(system_theme().unwrap_or(Theme::Light)); }); // Handle starting a build. - let on_rebuild = move |_| async move { - if build.stage().is_running() || !monaco_ready() { - return; - } - hot_reload.set_needs_rebuild(false); + let on_rebuild = use_callback(move |_| { + spawn(async move { + if build.stage().is_running() || !monaco_ready() { + return; + } + hot_reload.set_needs_rebuild(false); - // Update hot reload - let code = editor::monaco::get_current_model_value(); + // Update hot reload + let code = editor::monaco::get_current_model_value(); - let socket_url = urls.socket.to_string(); - match start_build(build, socket_url, code).await { - Ok(success) => hot_reload.set_needs_rebuild(!success), - Err(error) => errors.push_from_app_error(error), - } - }; + let socket_url = urls.socket.to_string(); + match start_build(build, socket_url, code).await { + Ok(success) => hot_reload.set_needs_rebuild(!success), + Err(error) => errors.push_from_app_error(error), + } + }); + }); // Construct the full URL to the built project. let built_page_url = use_memo(move || { @@ -147,7 +146,6 @@ pub fn Playground( script { src: monaco_loader_src(MONACO_FOLDER), onload: move |_| { - #[cfg(target_arch = "wasm32")] monaco::on_monaco_load( MONACO_FOLDER, system_theme().unwrap_or(Theme::Light), @@ -155,6 +153,7 @@ pub fn Playground( hot_reload, monaco_ready, on_model_changed, + on_rebuild ); }, } From 44db56406d6abb2b972e73782a43548fb5af3bd7 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 11:21:18 -0500 Subject: [PATCH 09/58] fix error messages --- packages/playground/model/src/lib.rs | 2 +- packages/playground/model/src/server.rs | 35 ++++++++++++++++++- .../playground/server/src/build/builder.rs | 11 +++++- packages/playground/server/src/main.rs | 4 +-- packages/playground/server/src/ws.rs | 4 +-- 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index e575c0a3e6..ee093bf4cc 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -60,7 +60,7 @@ impl SocketMessage { /// A cargo diagnostic #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct CargoDiagnostic { - pub target_crate: String, + pub target_crate: Option, pub level: CargoLevel, pub message: String, pub spans: Vec, diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 157ff7c106..a80c5f80fa 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -8,6 +8,7 @@ use crate::{ }; use axum::http::StatusCode; use axum::{extract::ws, response::IntoResponse}; +use dioxus_dx_wire_format::cargo_metadata::diagnostic::{Diagnostic, DiagnosticCode}; use dioxus_dx_wire_format::{ cargo_metadata::{diagnostic::DiagnosticLevel, CompilerMessage}, BuildStage as DxBuildStage, @@ -81,7 +82,39 @@ impl TryFrom for CargoDiagnostic { .collect(); Ok(Self { - target_crate: value.target.name, + target_crate: Some(value.target.name), + level, + message, + spans, + }) + } +} + +/// TryFrom that fails for data we don't care about from cargo. +impl TryFrom for CargoDiagnostic { + type Error = (); + + fn try_from(value: Diagnostic) -> Result { + let level = CargoLevel::Error; + + let message = value.message; + + // Collect spans + let spans = value + .spans + .iter() + .map(|s| CargoDiagnosticSpan { + is_primary: s.is_primary, + line_start: s.line_start, + line_end: s.line_end, + column_start: s.column_start, + column_end: s.column_end, + label: s.label.clone(), + }) + .collect(); + + Ok(Self { + target_crate: None, level, message, spans, diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 00eb088426..3bada55d86 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -220,7 +220,7 @@ fn process_dx_message(request: &BuildRequest, message: String) { }; // Don't send any diagnostics for dependencies. - if diagnostic.target_crate != format!("play-{}", request.id) { + if diagnostic.target_crate != Some(format!("play-{}", request.id)) { return; } @@ -228,6 +228,15 @@ fn process_dx_message(request: &BuildRequest, message: String) { .ws_msg_tx .send(BuildMessage::CargoDiagnostic(diagnostic)) } + StructuredOutput::RustcOutput { message } => { + let Ok(diagnostic) = CargoDiagnostic::try_from(message) else { + return; + }; + + request + .ws_msg_tx + .send(BuildMessage::CargoDiagnostic(diagnostic)) + } _ => Ok(()), }; } diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index b407be4c3d..9d51df23b0 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -83,8 +83,8 @@ async fn main() { })) .layer(BufferLayer::new(1024)) .layer(RateLimitLayer::new( - REQUESTS_PER_INTERVAL, - RATE_LIMIT_INTERVAL, + WS_REQUESTS_PER_INTERVAL, + WS_RATE_LIMIT_INTERVAL, )), ), ) diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index 81b9acc961..d46a08c3f6 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -1,9 +1,9 @@ use crate::{ - build::{BuildCommand, BuildMessage, BuildRequest}, AppState, + build::{BuildCommand, BuildMessage, BuildRequest}, }; use axum::{ - extract::{ws::WebSocket, State, WebSocketUpgrade}, + extract::{State, WebSocketUpgrade, ws::WebSocket}, response::IntoResponse, }; use axum_client_ip::ClientIp; From 74e867e95f5aa464d8ab3d55c64fed41827b2500 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 11:26:54 -0500 Subject: [PATCH 10/58] Fix showing error logs on the preview pannel --- packages/playground/playground/src/components/panes.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index bf287fca6c..f3dc28696d 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -124,7 +124,9 @@ pub fn Panes( Progress {} } else { // Viewport - if let Some(url) = built_page_url() { + if build_stage.is_err() { + Logs {} + } else if let Some(url) = built_page_url() { div { id: "dxp-viewport", iframe { id: "dxp-iframe", @@ -132,8 +134,6 @@ pub fn Panes( pointer_events: if dragging() { "none" } else { "all" }, } } - } else if build_stage.is_err() { - Logs {} } else { p { "Click `Rebuild` to start a build!" } } From cd622da2abef98fc97594a69ee08c86155268e59 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 11:34:58 -0500 Subject: [PATCH 11/58] clean up some lints --- packages/playground/model/src/server.rs | 4 +--- packages/playground/playground/src/components/header.rs | 5 ----- packages/playground/playground/src/editor/monaco.rs | 4 ++-- packages/playground/playground/src/share_code.rs | 2 +- packages/playground/server/src/main.rs | 2 +- packages/playground/server/src/serve.rs | 5 +---- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index a80c5f80fa..5e31910938 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -1,14 +1,12 @@ //! Server-specific implementations -use std::convert::Infallible; - use crate::{ AppError, BuildStage, CargoDiagnostic, CargoDiagnosticSpan, CargoLevel, SocketError, SocketMessage, }; use axum::http::StatusCode; use axum::{extract::ws, response::IntoResponse}; -use dioxus_dx_wire_format::cargo_metadata::diagnostic::{Diagnostic, DiagnosticCode}; +use dioxus_dx_wire_format::cargo_metadata::diagnostic::Diagnostic; use dioxus_dx_wire_format::{ cargo_metadata::{diagnostic::DiagnosticLevel, CompilerMessage}, BuildStage as DxBuildStage, diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index cb6d1e6848..3919025506 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -6,7 +6,6 @@ use dioxus::prelude::*; // use dioxus_sdk::utils::timing::use_debounce; use model::api::ApiClient; use model::Project; -use std::time::Duration; #[component] pub fn Header( @@ -23,10 +22,6 @@ pub fn Header( let mut errors = use_context::(); let mut share_btn_text = use_signal(|| "Share"); - // let mut reset_share_btn = use_debounce(Duration::from_secs(1), move |()| { - // share_btn_text.set("Share") - // }); - // reset_share_btn.action(()); rsx! { div { id: "dxp-header", diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index 22cc678257..eb30ab1eb1 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -56,8 +56,8 @@ pub fn on_monaco_load( contents: &str, mut hot_reload: HotReload, mut monaco_ready: Signal, - mut on_model_changed: Callback, - mut onbuild_callback: Callback<()>, + on_model_changed: Callback, + onbuild_callback: Callback<()>, ) { let on_ready_callback = Closure::new(move || monaco_ready.set(true)); let monaco_prefix = monaco_vs_prefix(folder); diff --git a/packages/playground/playground/src/share_code.rs b/packages/playground/playground/src/share_code.rs index 60344cd2e0..255e0becb7 100644 --- a/packages/playground/playground/src/share_code.rs +++ b/packages/playground/playground/src/share_code.rs @@ -1,4 +1,4 @@ -use dioxus::signals::{Signal, Writable, WritableExt}; +use dioxus::signals::{Signal, WritableExt}; use dioxus_document::eval; use model::{api::ApiClient, AppError, Project}; diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 9d51df23b0..2d41188440 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -28,7 +28,7 @@ const REQUESTS_PER_INTERVAL: u64 = 60; /// The period of time after the request limit resets. const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); /// How many websocket requests each user should get within a time period. -const WS_REQUESTS_PER_INTERVAL: u64 = 3; +const WS_REQUESTS_PER_INTERVAL: u64 = 6; /// The period of time after the request limit resets. const WS_RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); diff --git a/packages/playground/server/src/serve.rs b/packages/playground/server/src/serve.rs index 9ee2e47517..1dbe409a8b 100644 --- a/packages/playground/server/src/serve.rs +++ b/packages/playground/server/src/serve.rs @@ -1,13 +1,10 @@ use axum::{ - body::Body, extract::{Path, State}, - http::{header, StatusCode}, + http::StatusCode, response::IntoResponse, }; use dioxus_logger::tracing::warn; use std::path::PathBuf; -use tokio_util::io::ReaderStream; -use tower_http::services::{ServeDir, ServeFile}; use tower_util::ServiceExt; use uuid::Uuid; From 7020556a442226329f186f44987d755a9c404c5c Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 12:11:17 -0500 Subject: [PATCH 12/58] add per user rate limit and build rate limit --- Cargo.lock | 141 +++++++++++++++++- packages/playground/model/src/lib.rs | 2 + packages/playground/playground/src/build.rs | 8 +- .../playground/src/components/panes.rs | 14 +- packages/playground/playground/src/ws.rs | 1 + packages/playground/server/Cargo.toml | 2 + packages/playground/server/src/app.rs | 25 +++- packages/playground/server/src/main.rs | 30 ++-- packages/playground/server/src/ws.rs | 31 ++-- 9 files changed, 207 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c2c05aca8d..9aa411f670 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -922,7 +922,7 @@ dependencies = [ "futures-core", "prost", "prost-types", - "tonic", + "tonic 0.12.3", "tracing-core", ] @@ -946,7 +946,7 @@ dependencies = [ "thread_local", "tokio", "tokio-stream", - "tonic", + "tonic 0.12.3", "tracing", "tracing-core", "tracing-subscriber", @@ -2734,6 +2734,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror 1.0.69", +] + [[package]] name = "frontmatter" version = "0.4.0" @@ -2843,6 +2853,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" @@ -3025,9 +3041,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.7+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -3214,6 +3232,29 @@ dependencies = [ "system-deps", ] +[[package]] +name = "governor" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444405bbb1a762387aa22dd569429533b54a1d8759d35d3b64cb39b0293eaa19" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.3", + "hashbrown 0.15.5", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.2", + "smallvec", + "spinning_top", + "web-time", +] + [[package]] name = "gtk" version = "0.18.2" @@ -4667,6 +4708,18 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "noop_proc_macro" version = "0.3.0" @@ -5621,6 +5674,21 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.1+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-error" version = "2.0.1" @@ -5820,6 +5888,15 @@ dependencies = [ "rgb", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.9.4", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -6395,6 +6472,7 @@ dependencies = [ "example-projects", "fs_extra", "futures", + "governor", "model", "reqwest", "serde", @@ -6405,6 +6483,7 @@ dependencies = [ "tower 0.4.13", "tower-http 0.5.2", "tower-util", + "tower_governor", "tracing", "tracing-subscriber", "uuid", @@ -6706,6 +6785,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "srtparse" version = "0.2.0" @@ -7377,6 +7465,35 @@ dependencies = [ "tracing", ] +[[package]] +name = "tonic" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" +dependencies = [ + "async-trait", + "axum 0.8.4", + "base64 0.22.1", + "bytes", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-timeout", + "hyper-util", + "percent-encoding", + "pin-project 1.1.10", + "socket2 0.6.0", + "sync_wrapper", + "tokio", + "tokio-stream", + "tower 0.5.2", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.4.13" @@ -7405,9 +7522,12 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", + "indexmap 2.11.4", "pin-project-lite", + "slab", "sync_wrapper", "tokio", + "tokio-util", "tower-layer", "tower-service", "tracing", @@ -7492,6 +7612,23 @@ dependencies = [ "tower-service", ] +[[package]] +name = "tower_governor" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44de9b94d849d3c46e06a883d72d408c2de6403367b39df2b1c9d9e7b6736fe6" +dependencies = [ + "axum 0.8.4", + "forwarded-header-value", + "governor", + "http", + "pin-project 1.1.10", + "thiserror 2.0.16", + "tonic 0.14.2", + "tower 0.5.2", + "tracing", +] + [[package]] name = "tracing" version = "0.1.41" diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index ee093bf4cc..a938d52e0c 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; use std::error::Error; use std::string::FromUtf8Error; +use std::time::Duration; use thiserror::Error; use uuid::Uuid; @@ -22,6 +23,7 @@ pub enum SocketMessage { BuildStage(BuildStage), BuildDiagnostic(CargoDiagnostic), QueuePosition(usize), + RateLimited(Duration), AlreadyConnected, } diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index 126f3c3b02..ac3565ac68 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use crate::ws; use dioxus::prelude::*; use model::{AppError, CargoDiagnostic, Project, SocketMessage}; @@ -7,13 +9,17 @@ use uuid::Uuid; pub(crate) enum BuildStage { NotStarted, Starting, + Waiting(Duration), Building(model::BuildStage), Finished(Result), } impl BuildStage { pub fn is_running(&self) -> bool { - matches!(self, Self::Starting | Self::Building(..)) + matches!( + self, + Self::Starting | Self::Building(..) | Self::Waiting(..) + ) } pub fn is_finished(&self) -> bool { diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index f3dc28696d..4f41f13e73 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -155,16 +155,18 @@ fn Progress() -> Element { } match build.stage() { - BuildStage::NotStarted => "Build has not started.", - BuildStage::Starting => "Starting build...", + BuildStage::NotStarted => "Build has not started.".to_string(), + BuildStage::Starting => "Starting build...".to_string(), + BuildStage::Waiting(time) => { + format!("Rate limited, waiting {} seconds...", time.as_secs()) + } BuildStage::Building(build_stage) => match build_stage { - model::BuildStage::RunningBindgen => "Running wasm-bindgen...", - model::BuildStage::Other => "Computing...", + model::BuildStage::RunningBindgen => "Running wasm-bindgen...".to_string(), + model::BuildStage::Other => "Computing...".to_string(), model::BuildStage::Compiling { .. } => unreachable!(), }, - BuildStage::Finished(_) => "Finished!", + BuildStage::Finished(_) => "Finished!".to_string(), } - .to_string() }); // Determine the progress width. diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index 569e8e964c..25d1db26ba 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -47,6 +47,7 @@ pub fn handle_message(mut build: BuildState, message: SocketMessage) -> bool { return true; } SocketMessage::BuildDiagnostic(diagnostic) => build.push_diagnostic(diagnostic), + SocketMessage::RateLimited(time) => build.set_stage(BuildStage::Waiting(time)), _ => {} } diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index 27ce454ef6..c485431d5f 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -31,6 +31,8 @@ example-projects = { workspace = true } tracing = "0.1.41" tower-util = "0.3.1" tracing-subscriber = "0.3.20" +tower_governor = "0.8.0" +governor = "0.10.1" [features] tracing = ["tokio/tracing", "dep:console-subscriber"] diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 70d455e5ef..5f500d1403 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -1,18 +1,26 @@ //! Initialization of the server application and environment configurations. use crate::{ - build::{watcher::start_build_watcher, BuildCommand, BuildRequest}, + build::{BuildCommand, BuildRequest, watcher::start_build_watcher}, start_cleanup_services, }; use dioxus_logger::tracing::{info, warn}; +use governor::{ + Quota, RateLimiter, + clock::{QuantaClock, QuantaInstant}, + middleware::NoOpMiddleware, + state::keyed::DashMapStateStore, +}; use std::{ env, + net::IpAddr, + num::NonZeroU32, path::PathBuf, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, time::Duration, }; use tokio::{ - sync::{mpsc::UnboundedSender, Mutex}, + sync::{Mutex, mpsc::UnboundedSender}, time::Instant, }; @@ -161,6 +169,10 @@ pub struct AppState { pub _connected_sockets: Arc>>, pub reqwest_client: reqwest::Client, + + pub build_govener: Arc< + RateLimiter, QuantaClock, NoOpMiddleware>, + >, } impl AppState { @@ -184,6 +196,12 @@ impl AppState { env.shutdown_delay = Some(Duration::from_secs(1)); } + let build_govener = Arc::new(RateLimiter::keyed( + Quota::with_period(Duration::from_secs(30)) + .unwrap() + .allow_burst(NonZeroU32::new(2).unwrap()), + )); + let state = Self { env, build_queue_tx, @@ -191,6 +209,7 @@ impl AppState { is_building, _connected_sockets: Arc::new(Mutex::new(Vec::new())), reqwest_client: reqwest::Client::new(), + build_govener, }; // Queue the examples to be built on startup. diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 2d41188440..3efec49a14 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -14,6 +14,7 @@ use share::{get_shared_project, share_project}; use std::{io, net::SocketAddr, sync::atomic::Ordering, time::Duration}; use tokio::{net::TcpListener, select, time::Instant}; use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer}; +use tower_governor::{GovernorLayer, governor::GovernorConfigBuilder}; use tower_http::{compression::CompressionLayer, cors::CorsLayer}; mod app; @@ -27,10 +28,6 @@ mod ws; const REQUESTS_PER_INTERVAL: u64 = 60; /// The period of time after the request limit resets. const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); -/// How many websocket requests each user should get within a time period. -const WS_REQUESTS_PER_INTERVAL: u64 = 6; -/// The period of time after the request limit resets. -const WS_RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); #[tokio::main] async fn main() { @@ -63,6 +60,14 @@ async fn main() { false => ClientIpSource::ConnectInfo, }; + // Allow bursts with up to five requests per IP address + // and replenishes one element every 30 seconds + let governor_conf = GovernorConfigBuilder::default() + .per_second(60) + .burst_size(120) + .finish() + .unwrap(); + // Build the routers. let built_router = Router::new() .route("/", get(serve::serve_built_index)) @@ -73,21 +78,7 @@ async fn main() { .route("/{:id}", get(get_shared_project)); let app = Router::new() - .nest( - "/ws", - Router::new().route("/", get(ws::ws_handler)).layer( - ServiceBuilder::new() - .layer(HandleErrorLayer::new(|error: BoxError| async move { - error!(?error, "unhandled server error"); - (StatusCode::INTERNAL_SERVER_ERROR, "Internal Server Error") - })) - .layer(BufferLayer::new(1024)) - .layer(RateLimitLayer::new( - WS_REQUESTS_PER_INTERVAL, - WS_RATE_LIMIT_INTERVAL, - )), - ), - ) + .nest("/ws", Router::new().route("/", get(ws::ws_handler))) .nest("/built/{:build_id}", built_router) .nest("/shared", shared_router) .route( @@ -104,6 +95,7 @@ async fn main() { .layer(CompressionLayer::new()) .layer(CorsLayer::very_permissive()) .layer(BufferLayer::new(1024)) + .layer(GovernorLayer::new(governor_conf)) .layer(RateLimitLayer::new( REQUESTS_PER_INTERVAL, RATE_LIMIT_INTERVAL, diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index d46a08c3f6..5cff677279 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -1,3 +1,5 @@ +use std::net::IpAddr; + use crate::{ AppState, build::{BuildCommand, BuildMessage, BuildRequest}, @@ -9,6 +11,7 @@ use axum::{ use axum_client_ip::ClientIp; use dioxus_logger::tracing::error; use futures::{SinkExt, StreamExt as _}; +use governor::clock::{Clock, QuantaClock}; use model::{Project, SocketMessage}; use tokio::{ select, @@ -21,7 +24,6 @@ pub async fn ws_handler( ClientIp(ip): ClientIp, ws: WebSocketUpgrade, ) -> impl IntoResponse { - let ip = ip.to_string(); ws.on_upgrade(move |socket| handle_socket(state, ip, socket)) } @@ -31,23 +33,9 @@ pub async fn ws_handler( /// - Handle submitting build requests, allowing only one build per socket. /// - Send any build messages to the client. /// - Stop any ongoing builds if the connection closes. -async fn handle_socket(state: AppState, _ip: String, socket: WebSocket) { +async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { let (mut socket_tx, mut socket_rx) = socket.split(); - // Ensure only one client per socket. - // let mut connected_sockets = state.connected_sockets.lock().await; - // if connected_sockets.contains(&ip) { - // // Client is already connected. Send error and close socket. - // let _ = socket_tx - // .send(SocketMessage::AlreadyConnected.into_axum()) - // .await; - // let _ = socket_tx.close().await; - // return; - // } else { - // connected_sockets.push(ip.clone()); - // } - // drop(connected_sockets); - // Start our build loop. let (build_tx, mut build_rx) = mpsc::unbounded_channel(); let mut current_build: Option = None; @@ -71,6 +59,17 @@ async fn handle_socket(state: AppState, _ip: String, socket: WebSocket) { } } + // Rate limit the build requests by ip + if let Err(n) = state.build_govener.check_key(&ip) { + let wait_time = n.wait_time_from(QuantaClock::default().now()); + let socket_msg = SocketMessage::RateLimited(wait_time); + let socket_result = socket_tx.send(socket_msg.into_axum()).await; + if socket_result.is_err() { + break; + } + tokio::time::sleep(wait_time).await; + } + let request = start_build(&state, build_tx.clone(), code); current_build = Some(request); } From 64b0fa7e23d40638960937b87d3f233b12e7e606 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 24 Sep 2025 13:19:18 -0500 Subject: [PATCH 13/58] cleanup based on directory size instead of a timeout --- packages/playground/server/src/app.rs | 12 +++ packages/playground/server/src/main.rs | 105 +++++++++++++++++++------ 2 files changed, 91 insertions(+), 26 deletions(-) diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 5f500d1403..f6f03bb43f 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -31,6 +31,10 @@ const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; // Duration after built projects are created to be removed. const DEFAULT_BUILT_CLEANUP_DELAY: Duration = Duration::from_secs(20); +/// Max size of the built directory before old projects are removed. +const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB +/// Max size of the target directory before it is cleaned. +const DEFAULT_TARGET_DIR_SIZE: u64 = 3 * 1024 * 1024 * 1024; // 3 GB /// A group of environment configurations for the application. #[derive(Clone)] @@ -50,6 +54,12 @@ pub struct EnvVars { /// The time after creation each built project should be removed. pub built_cleanup_delay: Duration, + /// The max size of the built project directory before old projects are removed. + pub max_built_dir_size: u64, + + /// The max size of the target directory before it is cleaned. + pub max_target_dir_size: u64, + /// The optional shutdown delay that specifies how many seconds after /// inactivity to shut down the server. pub shutdown_delay: Option, @@ -77,6 +87,8 @@ impl EnvVars { }, shutdown_delay, built_cleanup_delay: DEFAULT_BUILT_CLEANUP_DELAY, + max_built_dir_size: DEFAULT_BUILT_DIR_SIZE, + max_target_dir_size: DEFAULT_TARGET_DIR_SIZE, gist_auth_token: gist_auth_token.unwrap_or_default(), } } diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 3efec49a14..55d9336097 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -138,7 +138,7 @@ fn start_cleanup_services(state: AppState) { select! { // Perform the next built project cleanup. _ = tokio::time::sleep_until(next_cleanup_check) => { - if let Err(e) = check_cleanup(state.clone()).await { + if let Err(e) = check_cleanup(&state).await { warn!("failed to clean built projects: {e}"); } } @@ -156,38 +156,91 @@ fn start_cleanup_services(state: AppState) { }); } -/// Check and cleanup any expired built projects. -async fn check_cleanup(state: AppState) -> Result<(), io::Error> { - let task = tokio::task::spawn_blocking(move || { - let dir = std::fs::read_dir(state.env.built_path)?; +/// Check and cleanup any expired built projects or the target dir +async fn check_cleanup(state: &AppState) -> Result<(), io::Error> { + check_project_cleanup(state).await?; + check_target_cleanup(state).await?; + Ok(()) +} - for item in dir { - let item = item?; - let path = item.path(); - let pathname = path.file_name().unwrap().to_string_lossy(); - - // Always cache the examples - don't remove those. - if example_projects::get_example_projects() - .iter() - .any(|p| p.id().to_string() == pathname) - { - continue; - } +/// Check and cleanup the target dir if it exceeds the max size. +async fn check_target_cleanup(state: &AppState) -> Result<(), io::Error> { + let target_path = state.env.build_template_path.join("target"); + let target_size = dir_size(&target_path).await?; + + if target_size > state.env.max_target_dir_size { + tokio::fs::remove_dir_all(&target_path).await?; + } + + Ok(()) +} + +/// Check and cleanup any expired built projects +async fn check_project_cleanup(state: &AppState) -> Result<(), io::Error> { + let mut dir = tokio::fs::read_dir(&state.env.built_path).await?; + let mut dirs_with_size = Vec::new(); + + while let Some(item) = dir.next_entry().await? { + let path = item.path(); + let pathname = path.file_name().unwrap().to_string_lossy(); + + // Always cache the examples - don't remove those. + if example_projects::get_example_projects() + .iter() + .any(|p| p.id().to_string() == pathname) + { + continue; + } + + let time_elapsed = item + .metadata() + .await + .and_then(|m| m.created()) + .and_then(|c| c.elapsed().map_err(io::Error::other))?; + let size = dir_size(&path).await?; + dirs_with_size.push((item, time_elapsed, size)); + } - let time_elapsed = item - .metadata() - .and_then(|m| m.created()) - .and_then(|c| c.elapsed().map_err(io::Error::other))?; + // Find the total size of the built directory. + let total_size: u64 = dirs_with_size.iter().map(|(_, _, size)| *size).sum(); + // If it exceeds the max, sort by oldest and remove until under the limit. + if total_size > state.env.max_built_dir_size { + dirs_with_size.sort_by_key(|(_, time_elapsed, _)| *time_elapsed); + let mut size = total_size; - if time_elapsed >= state.env.built_cleanup_delay { - std::fs::remove_dir_all(path)?; + for (item, _, dir_size) in dirs_with_size { + if size <= state.env.max_built_dir_size { + break; } + + let path = item.path(); + tokio::fs::remove_dir_all(&path).await?; + size -= dir_size; } + } - Ok(()) - }); + Ok(()) +} + +async fn dir_size(path: &std::path::Path) -> Result { + let mut size = 0; + let mut dirs = vec![path.to_path_buf()]; + + while let Some(dir) = dirs.pop() { + let mut entries = tokio::fs::read_dir(&dir).await?; + + while let Some(entry) = entries.next_entry().await? { + let metadata = entry.metadata().await?; + + if metadata.is_dir() { + dirs.push(entry.path()); + } else { + size += metadata.len(); + } + } + } - task.await.expect("task should not panic or abort") + Ok(size) } /// Check if the server should shutdown. From c2a8d50b06d8d6efc9f938cf5406139ffdffbe56 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 25 Sep 2025 11:33:34 -0500 Subject: [PATCH 14/58] Fix file cleanup logic --- packages/playground/server/src/app.rs | 6 - .../playground/server/src/build/builder.rs | 27 ++-- .../playground/server/src/build/cleanup.rs | 93 +++++++++++++ packages/playground/server/src/build/mod.rs | 1 + packages/playground/server/src/main.rs | 130 ++---------------- 5 files changed, 121 insertions(+), 136 deletions(-) create mode 100644 packages/playground/server/src/build/cleanup.rs diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index f6f03bb43f..e51b40c1ae 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -29,8 +29,6 @@ const DEFAULT_PORT: u16 = 3000; // Paths const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; -// Duration after built projects are created to be removed. -const DEFAULT_BUILT_CLEANUP_DELAY: Duration = Duration::from_secs(20); /// Max size of the built directory before old projects are removed. const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB /// Max size of the target directory before it is cleaned. @@ -51,9 +49,6 @@ pub struct EnvVars { /// The path where built projects are temporarily stored. pub built_path: PathBuf, - /// The time after creation each built project should be removed. - pub built_cleanup_delay: Duration, - /// The max size of the built project directory before old projects are removed. pub max_built_dir_size: u64, @@ -86,7 +81,6 @@ impl EnvVars { PathBuf::from("./temp/") }, shutdown_delay, - built_cleanup_delay: DEFAULT_BUILT_CLEANUP_DELAY, max_built_dir_size: DEFAULT_BUILT_DIR_SIZE, max_target_dir_size: DEFAULT_TARGET_DIR_SIZE, gist_auth_token: gist_auth_token.unwrap_or_default(), diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 3bada55d86..76d4609fcf 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -15,14 +15,14 @@ use tokio::io::{AsyncBufReadExt as _, BufReader}; use tokio::process::Command; use tokio::task::JoinHandle; use tokio::{fs, select}; +use tracing::warn; const BUILD_ID_ID: &str = "{BUILD_ID}"; // TODO: We need some way of cleaning up any stopped builds. /// The builder provides a convenient interface for controlling builds running in another task. pub struct Builder { - template_path: PathBuf, - built_path: PathBuf, + env: EnvVars, is_building: Arc, current_build: Option, task: Option>>, @@ -31,8 +31,7 @@ pub struct Builder { impl Builder { pub fn new(env: EnvVars, is_building: Arc) -> Self { Self { - template_path: env.build_template_path, - built_path: env.built_path, + env, is_building, current_build: None, task: None, @@ -46,11 +45,7 @@ impl Builder { self.stop_current(); self.is_building.store(true, Ordering::SeqCst); self.current_build = Some(request.clone()); - self.task = Some(tokio::spawn(build( - self.template_path.clone(), - self.built_path.clone(), - request, - ))); + self.task = Some(tokio::spawn(build(self.env.clone(), request))); } /// Stop the current build. @@ -89,17 +84,21 @@ impl Builder { } /// Run the steps to produce a build for a [`BuildRequest`] -async fn build( - template_path: PathBuf, - built_path: PathBuf, - request: BuildRequest, -) -> Result<(), BuildError> { +async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { + let built_path = &env.built_path; + let template_path = &env.build_template_path; + // If the project already exists, don't build it again. if std::fs::exists(built_path.join(request.id.to_string())).unwrap_or_default() { tracing::trace!("Skipping build for {request:?} since it already exists"); return Ok(()); } + // Check if we need to clean up old builds before starting a new one. + if let Err(e) = super::cleanup::check_cleanup(&env).await { + warn!("failed to clean built projects: {e}"); + } + setup_template(&template_path, &request).await?; dx_build(&template_path, &request).await?; move_to_built(&template_path, &built_path, &request).await?; diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs new file mode 100644 index 0000000000..6f6c73faf7 --- /dev/null +++ b/packages/playground/server/src/build/cleanup.rs @@ -0,0 +1,93 @@ +use std::io; + +use crate::app::EnvVars; + +/// Check and cleanup any expired built projects or the target dir +pub async fn check_cleanup(env: &EnvVars) -> Result<(), io::Error> { + check_project_cleanup(env).await?; + check_target_cleanup(env).await?; + Ok(()) +} + +/// Check and cleanup the target dir if it exceeds the max size. +async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { + let target_path = env.build_template_path.join("target"); + let target_size = dir_size(&target_path).await?; + + if target_size > env.max_target_dir_size { + tokio::fs::remove_dir_all(&target_path).await?; + } + + Ok(()) +} + +/// Check and cleanup any expired built projects +async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { + let mut dir = tokio::fs::read_dir(&env.built_path).await?; + let mut dirs_with_size = Vec::new(); + + while let Some(item) = dir.next_entry().await? { + let path = item.path(); + let pathname = path.file_name().unwrap().to_string_lossy(); + + // Always cache the examples - don't remove those. + if example_projects::get_example_projects() + .iter() + .any(|p| p.id().to_string() == pathname) + { + continue; + } + + let metadata = item.metadata().await; + let time_elapsed = metadata + .and_then(|m| m.created().or_else(|_| m.modified())) + .and_then(|c| c.elapsed().map_err(io::Error::other)); + let size = dir_size(&path).await; + if let (Ok(time_elapsed), Ok(size)) = (time_elapsed, size) { + dirs_with_size.push((item, time_elapsed, size)); + } else { + tracing::trace!("skipping cleanup of {pathname} due to error reading metadata") + } + } + + // Find the total size of the built directory. + let total_size: u64 = dirs_with_size.iter().map(|(_, _, size)| *size).sum(); + // If it exceeds the max, sort by oldest and remove until under the limit. + if total_size > env.max_built_dir_size { + dirs_with_size.sort_by_key(|(_, time_elapsed, _)| *time_elapsed); + let mut size = total_size; + + for (item, _, dir_size) in dirs_with_size { + if size <= env.max_built_dir_size { + break; + } + + let path = item.path(); + _ = tokio::fs::remove_dir_all(&path).await; + size -= dir_size; + } + } + + Ok(()) +} + +async fn dir_size(path: &std::path::Path) -> Result { + let mut size = 0; + let mut dirs = vec![path.to_path_buf()]; + + while let Some(dir) = dirs.pop() { + let mut entries = tokio::fs::read_dir(&dir).await?; + + while let Some(entry) = entries.next_entry().await.ok().flatten() { + let metadata = entry.metadata().await?; + + if metadata.is_dir() { + dirs.push(entry.path()); + } else { + size += metadata.len(); + } + } + } + + Ok(size) +} diff --git a/packages/playground/server/src/build/mod.rs b/packages/playground/server/src/build/mod.rs index fdda8914e1..18bf6dd9a4 100644 --- a/packages/playground/server/src/build/mod.rs +++ b/packages/playground/server/src/build/mod.rs @@ -6,6 +6,7 @@ use tokio::{sync::mpsc::UnboundedSender, task::JoinError}; use uuid::Uuid; pub mod builder; +pub mod cleanup; pub mod watcher; /// A build command which allows consumers of the builder api to submit and stop builds. diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 55d9336097..0b2e75dbd3 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -9,10 +9,10 @@ use axum::{ routing::{get, post}, }; use axum_client_ip::ClientIpSource; -use dioxus_logger::tracing::{Level, error, info, warn}; +use dioxus_logger::tracing::{Level, error, info}; use share::{get_shared_project, share_project}; -use std::{io, net::SocketAddr, sync::atomic::Ordering, time::Duration}; -use tokio::{net::TcpListener, select, time::Instant}; +use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration}; +use tokio::{net::TcpListener, time::Instant}; use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer}; use tower_governor::{GovernorLayer, governor::GovernorConfigBuilder}; use tower_http::{compression::CompressionLayer, cors::CorsLayer}; @@ -123,124 +123,22 @@ async fn main() { /// Start misc services for maintaining the server's operation. fn start_cleanup_services(state: AppState) { - tokio::task::spawn(async move { - let cleanup_delay = state.env.built_cleanup_delay; - let shutdown_delay = state - .env - .shutdown_delay - .unwrap_or(Duration::from_secs(99999999)); - - loop { - let now = Instant::now(); - let next_shutdown_check = now + shutdown_delay; - let next_cleanup_check = now + cleanup_delay; - - select! { - // Perform the next built project cleanup. - _ = tokio::time::sleep_until(next_cleanup_check) => { - if let Err(e) = check_cleanup(&state).await { - warn!("failed to clean built projects: {e}"); - } - } + if let Some(shutdown_delay) = state.env.shutdown_delay { + tokio::task::spawn(async move { + loop { + let now = Instant::now(); + let next_shutdown_check = now + shutdown_delay; // Check if server should shut down. - _ = tokio::time::sleep_until(next_shutdown_check), if state.env.shutdown_delay.is_some() => { - let should_shutdown = check_shutdown(&state, &shutdown_delay).await; - if should_shutdown { - // TODO: We could be more graceful here. - std::process::exit(0); - } + tokio::time::sleep_until(next_shutdown_check).await; + let should_shutdown = check_shutdown(&state, &shutdown_delay).await; + if should_shutdown { + // TODO: We could be more graceful here. + std::process::exit(0); } } - } - }); -} - -/// Check and cleanup any expired built projects or the target dir -async fn check_cleanup(state: &AppState) -> Result<(), io::Error> { - check_project_cleanup(state).await?; - check_target_cleanup(state).await?; - Ok(()) -} - -/// Check and cleanup the target dir if it exceeds the max size. -async fn check_target_cleanup(state: &AppState) -> Result<(), io::Error> { - let target_path = state.env.build_template_path.join("target"); - let target_size = dir_size(&target_path).await?; - - if target_size > state.env.max_target_dir_size { - tokio::fs::remove_dir_all(&target_path).await?; - } - - Ok(()) -} - -/// Check and cleanup any expired built projects -async fn check_project_cleanup(state: &AppState) -> Result<(), io::Error> { - let mut dir = tokio::fs::read_dir(&state.env.built_path).await?; - let mut dirs_with_size = Vec::new(); - - while let Some(item) = dir.next_entry().await? { - let path = item.path(); - let pathname = path.file_name().unwrap().to_string_lossy(); - - // Always cache the examples - don't remove those. - if example_projects::get_example_projects() - .iter() - .any(|p| p.id().to_string() == pathname) - { - continue; - } - - let time_elapsed = item - .metadata() - .await - .and_then(|m| m.created()) - .and_then(|c| c.elapsed().map_err(io::Error::other))?; - let size = dir_size(&path).await?; - dirs_with_size.push((item, time_elapsed, size)); + }); } - - // Find the total size of the built directory. - let total_size: u64 = dirs_with_size.iter().map(|(_, _, size)| *size).sum(); - // If it exceeds the max, sort by oldest and remove until under the limit. - if total_size > state.env.max_built_dir_size { - dirs_with_size.sort_by_key(|(_, time_elapsed, _)| *time_elapsed); - let mut size = total_size; - - for (item, _, dir_size) in dirs_with_size { - if size <= state.env.max_built_dir_size { - break; - } - - let path = item.path(); - tokio::fs::remove_dir_all(&path).await?; - size -= dir_size; - } - } - - Ok(()) -} - -async fn dir_size(path: &std::path::Path) -> Result { - let mut size = 0; - let mut dirs = vec![path.to_path_buf()]; - - while let Some(dir) = dirs.pop() { - let mut entries = tokio::fs::read_dir(&dir).await?; - - while let Some(entry) = entries.next_entry().await? { - let metadata = entry.metadata().await?; - - if metadata.is_dir() { - dirs.push(entry.path()); - } else { - size += metadata.len(); - } - } - } - - Ok(size) } /// Check if the server should shutdown. From 13bc855116783291d76c6cc1c4fe7dc14d87511b Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 25 Sep 2025 12:04:00 -0500 Subject: [PATCH 15/58] add a memory limit to dx --- Cargo.lock | 1 + packages/playground/server/Cargo.toml | 1 + packages/playground/server/src/app.rs | 7 +++++ .../playground/server/src/build/builder.rs | 28 +++++++++++++++++-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9aa411f670..6eed28e9f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6475,6 +6475,7 @@ dependencies = [ "governor", "model", "reqwest", + "rustix", "serde", "serde_json", "thiserror 2.0.16", diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index c485431d5f..29ddb144a7 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -33,6 +33,7 @@ tower-util = "0.3.1" tracing-subscriber = "0.3.20" tower_governor = "0.8.0" governor = "0.10.1" +rustix = { version = "1.1.2", features = ["process"] } [features] tracing = ["tokio/tracing", "dep:console-subscriber"] diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index e51b40c1ae..3095b6e251 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -31,6 +31,8 @@ const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; /// Max size of the built directory before old projects are removed. const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB +/// Max memory usage of dx during a build before it is killed. +const DEFAULT_DX_MEMORY_LIMIT: u64 = 1 * 1024 * 1024 * 1024; // 1 GB /// Max size of the target directory before it is cleaned. const DEFAULT_TARGET_DIR_SIZE: u64 = 3 * 1024 * 1024 * 1024; // 3 GB @@ -55,6 +57,10 @@ pub struct EnvVars { /// The max size of the target directory before it is cleaned. pub max_target_dir_size: u64, + /// The max memory limit for dx during a build. + #[cfg_attr(not(target_os = "linux"), allow(unused))] + pub dx_memory_limit: u64, + /// The optional shutdown delay that specifies how many seconds after /// inactivity to shut down the server. pub shutdown_delay: Option, @@ -83,6 +89,7 @@ impl EnvVars { shutdown_delay, max_built_dir_size: DEFAULT_BUILT_DIR_SIZE, max_target_dir_size: DEFAULT_TARGET_DIR_SIZE, + dx_memory_limit: DEFAULT_DX_MEMORY_LIMIT, gist_auth_token: gist_auth_token.unwrap_or_default(), } } diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 76d4609fcf..52186ecaf9 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -12,7 +12,7 @@ use std::process::Stdio; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use tokio::io::{AsyncBufReadExt as _, BufReader}; -use tokio::process::Command; +use tokio::process::{Child, Command}; use tokio::task::JoinHandle; use tokio::{fs, select}; use tracing::warn; @@ -100,7 +100,7 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { } setup_template(&template_path, &request).await?; - dx_build(&template_path, &request).await?; + dx_build(&template_path, &request, &env).await?; move_to_built(&template_path, &built_path, &request).await?; Ok(()) @@ -139,7 +139,11 @@ async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result< /// Run the build command provided by the DX CLI. /// Returns if DX built the project successfully. -async fn dx_build(template_path: &PathBuf, request: &BuildRequest) -> Result<(), BuildError> { +async fn dx_build( + template_path: &PathBuf, + request: &BuildRequest, + env: &EnvVars, +) -> Result<(), BuildError> { let mut child = Command::new("dx") .arg("build") .arg("--platform") @@ -152,6 +156,8 @@ async fn dx_build(template_path: &PathBuf, request: &BuildRequest) -> Result<(), .stderr(Stdio::piped()) .spawn()?; + set_dx_limits(&child, env); + let stdout = child.stdout.take().expect("dx stdout should exist"); let mut stdout_reader = BufReader::new(stdout).lines(); @@ -196,6 +202,22 @@ async fn dx_build(template_path: &PathBuf, request: &BuildRequest) -> Result<(), Ok(()) } +#[allow(unused)] +fn set_dx_limits(process: &Child, env: &EnvVars) { + #[cfg(any(target_os = "android", target_os = "linux"))] + { + let id = process.id(); + let new = Rlimit { + current: None, + maximum: Some(env.dx_memory_limit), + }; + + if let Err(err) = rustix::process::prlimit(None, Resource::Core, new.clone()) { + warn!("failed to set core limit for dx process {id}: {err}"); + } + } +} + /// Process a JSON-formatted message from the DX CLI, returning nothing on error. /// /// We don't care if this errors as it is human-readable output which the playground doesn't depend on for build status. From 87d357cb6aef04a618abc02ad3c6e62d51be7d2e Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 25 Sep 2025 12:16:50 -0500 Subject: [PATCH 16/58] limit the amount of memory dx can use --- packages/playground/server/src/app.rs | 7 +++++++ packages/playground/server/src/build/builder.rs | 15 ++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 3095b6e251..87aa3af7d4 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -33,6 +33,8 @@ const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB /// Max memory usage of dx during a build before it is killed. const DEFAULT_DX_MEMORY_LIMIT: u64 = 1 * 1024 * 1024 * 1024; // 1 GB +/// Max seconds a dx build can take before it is killed. +const DEFAULT_DX_BUILD_TIMEOUT: u64 = 300; // 5 minutes /// Max size of the target directory before it is cleaned. const DEFAULT_TARGET_DIR_SIZE: u64 = 3 * 1024 * 1024 * 1024; // 3 GB @@ -61,6 +63,10 @@ pub struct EnvVars { #[cfg_attr(not(target_os = "linux"), allow(unused))] pub dx_memory_limit: u64, + /// The max seconds a dx build can take before it is killed. + #[cfg_attr(not(target_os = "linux"), allow(unused))] + pub dx_build_timeout: u64, + /// The optional shutdown delay that specifies how many seconds after /// inactivity to shut down the server. pub shutdown_delay: Option, @@ -90,6 +96,7 @@ impl EnvVars { max_built_dir_size: DEFAULT_BUILT_DIR_SIZE, max_target_dir_size: DEFAULT_TARGET_DIR_SIZE, dx_memory_limit: DEFAULT_DX_MEMORY_LIMIT, + dx_build_timeout: DEFAULT_DX_BUILD_TIMEOUT, gist_auth_token: gist_auth_token.unwrap_or_default(), } } diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 52186ecaf9..b51b9f6e72 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -207,13 +207,22 @@ fn set_dx_limits(process: &Child, env: &EnvVars) { #[cfg(any(target_os = "android", target_os = "linux"))] { let id = process.id(); - let new = Rlimit { + let memory_limit = Rlimit { current: None, maximum: Some(env.dx_memory_limit), }; - if let Err(err) = rustix::process::prlimit(None, Resource::Core, new.clone()) { - warn!("failed to set core limit for dx process {id}: {err}"); + if let Err(err) = rustix::process::prlimit(None, Resource::As, memory_limit) { + warn!("failed to set memory limit for dx process {id}: {err}"); + } + + let cpu_limit = Rlimit { + current: None, + maximum: Some(env.dx_build_timeout), + }; + + if let Err(err) = rustix::process::prlimit(None, Resource::Cpu, cpu_limit) { + warn!("failed to set cpu time limit for dx process {id}: {err}"); } } } From d10c419468ab1c76cb5f6ba3736a78b261374da1 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 26 Sep 2025 09:11:03 -0500 Subject: [PATCH 17/58] lower default timeout --- Dockerfile | 4 +- fly.toml | 2 +- packages/playground/server/src/app.rs | 4 +- .../playground/server/src/build/builder.rs | 87 ++++++++++--------- packages/playground/server/test.rs | 44 ++++++++++ 5 files changed, 93 insertions(+), 48 deletions(-) create mode 100644 packages/playground/server/test.rs diff --git a/Dockerfile b/Dockerfile index e117970be9..f3f286ba3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1-bookworm AS chef +FROM rust:1-trixie AS chef RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash RUN cargo binstall cargo-chef --no-confirm @@ -22,7 +22,7 @@ COPY . . RUN cargo build --release --bin server # Pre-slim runtime -FROM rust:1-slim-bookworm AS pre-runtime +FROM rust:1-slim-trixie AS pre-runtime # Install openssl RUN set -ex; \ diff --git a/fly.toml b/fly.toml index f4daca6e42..2bbb8593bb 100644 --- a/fly.toml +++ b/fly.toml @@ -38,6 +38,6 @@ kill_timeout = '5s' soft_limit = 20 [[vm]] - memory = '1gb' + memory = '3gb' cpu_kind = 'shared' cpus = 2 diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 87aa3af7d4..bd7204d5d7 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -32,9 +32,9 @@ const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; /// Max size of the built directory before old projects are removed. const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB /// Max memory usage of dx during a build before it is killed. -const DEFAULT_DX_MEMORY_LIMIT: u64 = 1 * 1024 * 1024 * 1024; // 1 GB +const DEFAULT_DX_MEMORY_LIMIT: u64 = 5 * 1024 * 1024 * 1024; // 5 GB /// Max seconds a dx build can take before it is killed. -const DEFAULT_DX_BUILD_TIMEOUT: u64 = 300; // 5 minutes +const DEFAULT_DX_BUILD_TIMEOUT: u64 = 30; // 30 seconds /// Max size of the target directory before it is cleaned. const DEFAULT_TARGET_DIR_SIZE: u64 = 3 * 1024 * 1024 * 1024; // 3 GB diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index b51b9f6e72..fd41aeb0a0 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -7,14 +7,14 @@ use dioxus_logger::tracing::debug; use fs_extra::dir::CopyOptions; use model::{BuildStage, CargoDiagnostic}; use std::future::pending; +use std::io::{BufRead, BufReader}; use std::path::{Path, PathBuf}; use std::process::Stdio; +use std::process::{Child, Command}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; -use tokio::io::{AsyncBufReadExt as _, BufReader}; -use tokio::process::{Child, Command}; +use tokio::fs; use tokio::task::JoinHandle; -use tokio::{fs, select}; use tracing::warn; const BUILD_ID_ID: &str = "{BUILD_ID}"; @@ -100,7 +100,13 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { } setup_template(&template_path, &request).await?; - dx_build(&template_path, &request, &env).await?; + tokio::task::spawn_blocking({ + let template_path = template_path.to_path_buf(); + let request = request.clone(); + let env = env.clone(); + move || dx_build(&template_path, &request, &env) + }) + .await??; move_to_built(&template_path, &built_path, &request).await?; Ok(()) @@ -139,7 +145,7 @@ async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result< /// Run the build command provided by the DX CLI. /// Returns if DX built the project successfully. -async fn dx_build( +fn dx_build( template_path: &PathBuf, request: &BuildRequest, env: &EnvVars, @@ -158,70 +164,65 @@ async fn dx_build( set_dx_limits(&child, env); + let stderr = child.stderr.take().expect("dx stdout should exist"); let stdout = child.stdout.take().expect("dx stdout should exist"); let mut stdout_reader = BufReader::new(stdout).lines(); + let mut stderr_reader = BufReader::new(stderr).lines(); let mut logs = Vec::new(); - loop { - select! { - // Read stdout lines from DX. - result = stdout_reader.next_line() => { - let Ok(Some(line)) = result else { - continue; - }; - - logs.push(line.clone()); - process_dx_message(request, line); + tracing::info!("Starting build for request id {}", request.id); + while let Some(Ok(line)) = stdout_reader.next() { + logs.push(line.clone()); + process_dx_message(request, line); + } + let status = child.wait(); + tracing::info!( + "got status from dx build for request id {}: {status:?}", + request.id + ); + // Check if the build was successful. + let exit_code = status.map(|c| c.code()); + if let Ok(Some(code)) = exit_code { + if code == 0 { + return Ok(()); + } else { + // Dump logs in debug. + for log in logs { + debug!("{log}"); } - // Wait for the DX process to exit. - status = child.wait() => { - while let Ok(Some(line)) = stdout_reader.next_line().await { - logs.push(line.clone()); - process_dx_message(request, line); - } - // Check if the build was successful. - let exit_code = status.map(|c| c.code()); - if let Ok(Some(code)) = exit_code { - if code == 0 { - break; - } else { - // Dump logs in debug. - for log in logs { - debug!("{log}"); - } - - return Err(BuildError::DxFailed(Some(code))); - } - } - return Err(BuildError::DxFailed(None)); + while let Some(Ok(line)) = stderr_reader.next() { + warn!("dx stderr: {line}"); } + + return Err(BuildError::DxFailed(Some(code))); } } - - Ok(()) + Err(BuildError::DxFailed(None)) } #[allow(unused)] fn set_dx_limits(process: &Child, env: &EnvVars) { + // TODO this isn't working, not sure why #[cfg(any(target_os = "android", target_os = "linux"))] { - let id = process.id(); + use rustix::process::{Resource, Rlimit}; + let id = rustix::process::Pid::from_child(process); let memory_limit = Rlimit { - current: None, + current: Some(env.dx_memory_limit), maximum: Some(env.dx_memory_limit), }; - if let Err(err) = rustix::process::prlimit(None, Resource::As, memory_limit) { + if let Err(err) = rustix::process::prlimit(Some(id), Resource::As, memory_limit) { warn!("failed to set memory limit for dx process {id}: {err}"); } let cpu_limit = Rlimit { - current: None, + current: Some(env.dx_build_timeout), maximum: Some(env.dx_build_timeout), }; - if let Err(err) = rustix::process::prlimit(None, Resource::Cpu, cpu_limit) { + if let Err(err) = rustix::process::prlimit(Some(id), Resource::Cpu, cpu_limit) { warn!("failed to set cpu time limit for dx process {id}: {err}"); } } diff --git a/packages/playground/server/test.rs b/packages/playground/server/test.rs new file mode 100644 index 0000000000..e4dbd346f6 --- /dev/null +++ b/packages/playground/server/test.rs @@ -0,0 +1,44 @@ +// From https://github.com/rust-lang/rust/issues/132558 +//#![recursion_limit = "10"] + +trait S { + type Child: S; +} + +impl S for (X, X) { + // Recursing "inwards" here using `X::Child` seems to be + // important. E.g. if I instead define + // + //type Child = ((X, X), (X, X)); + // + // which is just as exponential, but not recursive, then the compiler again + // gives the correct "recursion depth exceeded" error with the default and + // small recursion limits. + type Child = (X::Child, X::Child); +} + +impl S for Box { + type Child = X; +} + +type Data = Box<(A, A)>; +struct A {} +impl S for A { + // Manually expanding the `Data::Child` here fixes the bug both for a small + // recursion limit, and for the default recursion limit, i.e. the compiler + // gives a "recursion depth exceeded" error message in both cases. This is + // in contrast to the version above in my report, where expanding the + // `Data::Child` type fixes the bug for the small recursion limit, but the + // compiler still hangs for the default recursion limit. + // + //type Child = (A, A); + type Child = ::Child; +} + +fn uhoh() { + uhoh::(); +} + +fn main() { + uhoh::(); +} From 313b0339d81585f30e75219728dd90afcc73abad Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 26 Sep 2025 12:02:39 -0500 Subject: [PATCH 18/58] hide env vars --- packages/playground/server/src/build/builder.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index fd41aeb0a0..af7db78f4f 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -150,6 +150,10 @@ fn dx_build( request: &BuildRequest, env: &EnvVars, ) -> Result<(), BuildError> { + let filtered_vars = std::env::vars().filter(|(k, _)| { + let allowed = ["RUST_VERSION", "RUSTUP_HOME", "CARGO_HOME", "PATH", "HOME"]; + allowed.contains(&k.as_str()) + }); let mut child = Command::new("dx") .arg("build") .arg("--platform") @@ -157,6 +161,8 @@ fn dx_build( .arg("--json-output") .arg("--verbose") .arg("--trace") + .env_clear() + .envs(filtered_vars) .current_dir(template_path) .stdout(Stdio::piped()) .stderr(Stdio::piped()) @@ -171,16 +177,11 @@ fn dx_build( let mut logs = Vec::new(); - tracing::info!("Starting build for request id {}", request.id); while let Some(Ok(line)) = stdout_reader.next() { logs.push(line.clone()); process_dx_message(request, line); } let status = child.wait(); - tracing::info!( - "got status from dx build for request id {}: {status:?}", - request.id - ); // Check if the build was successful. let exit_code = status.map(|c| c.code()); if let Ok(Some(code)) = exit_code { From 21c2b8c8b4e27f418a6eae462ad61d7b16f27bf6 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 26 Sep 2025 13:25:28 -0500 Subject: [PATCH 19/58] handle hot patching from the server side --- Cargo.lock | 154 +++++++++++++----- Cargo.toml | 1 + packages/playground/server/Cargo.toml | 1 + packages/playground/server/src/app.rs | 13 ++ .../playground/server/src/build/builder.rs | 84 ++++++++-- .../playground/server/src/build/cleanup.rs | 2 +- 6 files changed, 191 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6eed28e9f7..af170f9245 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1356,7 +1356,7 @@ dependencies = [ "dioxus-cli-config", "dioxus-config-macro", "dioxus-config-macros", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-macro", "dioxus-devtools", "dioxus-document", @@ -1375,7 +1375,7 @@ dependencies = [ "dioxus_server_macro", "manganis", "serde", - "subsecond", + "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "warnings", ] @@ -1448,17 +1448,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07b55eccaa5c4f35f1755ea18a5716fe8ecba60ff1f25c52be6ceda2e6a52eb6" dependencies = [ "const_format", - "dioxus-core-types", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "longest-increasing-subsequence", "rustc-hash 2.1.1", "rustversion", "serde", "slab", "slotmap", - "subsecond", + "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing", + "warnings", +] + +[[package]] +name = "dioxus-core" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +dependencies = [ + "const_format", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "futures-channel", + "futures-util", + "generational-box 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "longest-increasing-subsequence", + "rustc-hash 2.1.1", + "rustversion", + "serde", + "slab", + "slotmap", + "subsecond 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", "tracing", "warnings", ] @@ -1482,6 +1503,11 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0ef2a94b4ceb8f7a39f56a539d07e82b0358a49a0b95028ad48635975df29d7" +[[package]] +name = "dioxus-core-types" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" + [[package]] name = "dioxus-desktop" version = "0.7.0-rc.0" @@ -1494,7 +1520,7 @@ dependencies = [ "core-foundation 0.10.1", "dioxus-asset-resolver", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-devtools", "dioxus-document", "dioxus-history", @@ -1505,7 +1531,7 @@ dependencies = [ "dunce", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "global-hotkey", "infer", "jni", @@ -1543,12 +1569,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60af4e129968ab1713471ed0b29c3eefa4e8e09252429487d7a581e93c7ecfe5" dependencies = [ "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-devtools-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "serde", "serde_json", - "subsecond", + "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 2.0.16", "tracing", "tungstenite 0.27.0", @@ -1561,11 +1587,21 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64274704b6a8d018112473cdce0b3db1dcccfa79bde445223592fe4e396ff5ef" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "subsecond-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dioxus-devtools-types" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +dependencies = [ + "dioxus-core 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "serde", + "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", +] + [[package]] name = "dioxus-docs-03" version = "0.0.0" @@ -1686,13 +1722,13 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11c7f4ff62a842c026c74b9782dd9117a2310ec52de69d858a9e54b96b3bac15" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-macro", - "dioxus-core-types", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-html", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy-js-bundle", "serde", "serde_json", @@ -1720,7 +1756,7 @@ dependencies = [ "base64 0.22.1", "bytes", "ciborium", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-devtools", "dioxus-document", "dioxus-fullstack-hooks", @@ -1732,7 +1768,7 @@ dependencies = [ "dioxus_server_macro", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "http", "serde", "server_fn", @@ -1746,7 +1782,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef5fad61b2821b8f26c8498834920d617449d0b866aaac01b95284237f76e9d5" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-fullstack-protocol", "dioxus-history", "dioxus-hooks", @@ -1763,7 +1799,7 @@ checksum = "b2f266ad9e20be14b8899f2133dd942131f03e6749650e65e2aaec2c7f8a4bc1" dependencies = [ "base64 0.22.1", "ciborium", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", "tracing", ] @@ -1774,7 +1810,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e9e34323717a78ea3f8ba5072ff484744a656e8d422932c19937b67f45113e" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "tracing", ] @@ -1784,11 +1820,11 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab776b9a156765cc7dd7876891c98b9ab06b1f995d33ff169b06ef4f23cfd437" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustversion", "slab", "tracing", @@ -1802,16 +1838,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "073e5b69a7b66e9cbb49530df8c4cf86bf2aff3322ba86a3d722f9d58cd9c54b" dependencies = [ "async-trait", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-macro", - "dioxus-core-types", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-hooks", "dioxus-html-internal-macro", "dioxus-rsx", "enumset", "euclid", "futures-channel", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "keyboard-types", "lazy-js-bundle", "rustversion", @@ -1839,8 +1875,8 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd2ef3fe9bddfcac6d2ccf123d4834b5c3d97e6f2be8fcbfc4943226d9d7d4fe" dependencies = [ - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-html", "js-sys", "lazy-js-bundle", @@ -1876,7 +1912,7 @@ checksum = "f90ea4ac81b0c239f00c70a06d1433135babca3412817d4c21a1a188964e5a7f" dependencies = [ "axum 0.8.4", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-devtools", "dioxus-document", "dioxus-history", @@ -1884,7 +1920,7 @@ dependencies = [ "dioxus-interpreter-js", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", "serde", "serde_json", @@ -1916,8 +1952,8 @@ dependencies = [ "base64 0.22.1", "dioxus", "dioxus-autofmt", - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-devtools", "dioxus-document", "dioxus-html", @@ -1948,7 +1984,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6260ba0131670716b7410bc6b2eba13cc7677ba133c9678b5508214a7a2a1794" dependencies = [ "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-macro", "dioxus-fullstack-hooks", "dioxus-history", @@ -1995,8 +2031,8 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c796e02557a4de1f4b4850e554b802b7bcce607103e0b1d5b4c530268791005e" dependencies = [ - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-rsx", "internment", "proc-macro2", @@ -2089,7 +2125,7 @@ dependencies = [ "ciborium", "dashmap", "dioxus-cli-config", - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-macro", "dioxus-devtools", "dioxus-document", @@ -2105,7 +2141,7 @@ dependencies = [ "enumset", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "http", "hyper", "hyper-util", @@ -2114,7 +2150,7 @@ dependencies = [ "pin-project 1.1.10", "serde", "server_fn", - "subsecond", + "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 2.0.16", "tokio", "tokio-util", @@ -2132,10 +2168,10 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1d0e70a8da969c0404f5ef8cf6f47042bea55608b582079f3ea3d9fff46125c" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot", "rustc-hash 2.1.1", "tracing", @@ -2149,8 +2185,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21c377da1f2ea708be1112dd61189d6dcd19c8db25208b750c3849f760fa854d" dependencies = [ "askama_escape 0.13.0", - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", ] @@ -2160,7 +2196,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5494e5aa7333f3be918741eeb6bfb4d1cbf28d25035a2a3c2c5bcebdc27b0b68" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "dioxus-stores-macro", ] @@ -2205,8 +2241,8 @@ checksum = "34eb4f341b0203f7b1fe1804d4561a19a399bf7fa4821a5b87cff5fd89d834bd" dependencies = [ "async-trait", "dioxus-cli-config", - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-devtools", "dioxus-document", "dioxus-fullstack-protocol", @@ -2216,7 +2252,7 @@ dependencies = [ "dioxus-signals", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "gloo-timers", "js-sys", "lazy-js-bundle", @@ -2981,6 +3017,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "generational-box" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +dependencies = [ + "parking_lot", + "tracing", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -4298,7 +4343,7 @@ checksum = "6d71ef461824c58f3d260c1f548f7a8aee2e0b6b805a503d15f8535a3a6272d7" dependencies = [ "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-cli-config", - "dioxus-core-types", + "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", ] @@ -6467,6 +6512,7 @@ dependencies = [ "axum-client-ip", "console-subscriber", "dioxus", + "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", "dioxus-dx-wire-format", "dioxus-logger", "example-projects", @@ -6887,6 +6933,24 @@ dependencies = [ "web-sys", ] +[[package]] +name = "subsecond" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +dependencies = [ + "js-sys", + "libc", + "libloading 0.8.9", + "memfd", + "memmap2", + "serde", + "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "thiserror 2.0.16", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "subsecond-types" version = "0.7.0-rc.0" diff --git a/Cargo.toml b/Cargo.toml index d27fc7f959..38e7890c7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ dioxus-html = { version = "0.7.0-rc.0", default-features = false } dioxus-rsx-rosetta = "0.7.0-rc.0" dioxus-autofmt = "0.7.0-rc.0" dioxus-dx-wire-format = { git = "https://github.com/DioxusLabs/dioxus" } +dioxus-devtools-types = { git = "https://github.com/DioxusLabs/dioxus" } dioxus-logger = "0.7.0-rc.0" # 3rd-party dioxus diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index 29ddb144a7..d984d4cc8b 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -12,6 +12,7 @@ serde_json = { workspace = true } dioxus-logger = { workspace = true } dioxus-dx-wire-format = { workspace = true } +dioxus-devtools-types = { workspace = true } axum = { workspace = true, features = ["ws", "macros"] } axum-client-ip = "1.1" diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index bd7204d5d7..a989b9544c 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -23,6 +23,7 @@ use tokio::{ sync::{Mutex, mpsc::UnboundedSender}, time::Instant, }; +use uuid::Uuid; const DEFAULT_PORT: u16 = 3000; @@ -101,6 +102,18 @@ impl EnvVars { } } + /// Get the path to the target dir + pub fn target_dir(&self) -> PathBuf { + self.build_template_path.join("target") + } + + /// Get the path to the built template hot patch cache + pub fn built_template_hotpatch_cache(&self, id: &Uuid) -> PathBuf { + self.target_dir() + .join("hotpatch_cache") + .join(id.to_string()) + } + /// Get the production environment variable. fn get_production_env() -> bool { let production = env::var("PRODUCTION") diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index af7db78f4f..516e36bf7d 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -104,7 +104,7 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { let template_path = template_path.to_path_buf(); let request = request.clone(); let env = env.clone(); - move || dx_build(&template_path, &request, &env) + move || dx_build(&&request, &env) }) .await??; move_to_built(&template_path, &built_path, &request).await?; @@ -143,33 +143,70 @@ async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result< Ok(()) } -/// Run the build command provided by the DX CLI. -/// Returns if DX built the project successfully. -fn dx_build( - template_path: &PathBuf, - request: &BuildRequest, - env: &EnvVars, -) -> Result<(), BuildError> { +/// Start a process with limited access to the environment and resources +fn start_limited_process(mut command: Command, env: &EnvVars) -> Result { let filtered_vars = std::env::vars().filter(|(k, _)| { let allowed = ["RUST_VERSION", "RUSTUP_HOME", "CARGO_HOME", "PATH", "HOME"]; allowed.contains(&k.as_str()) }); - let mut child = Command::new("dx") - .arg("build") - .arg("--platform") - .arg("web") - .arg("--json-output") - .arg("--verbose") - .arg("--trace") + + let child = command .env_clear() .envs(filtered_vars) - .current_dir(template_path) + .current_dir(&env.build_template_path) + .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn()?; set_dx_limits(&child, env); + Ok(child) +} + +/// Run the build command provided by the DX CLI. +/// Returns if DX built the project successfully. +fn dx_build(request: &BuildRequest, env: &EnvVars) -> Result<(), BuildError> { + let cache_dir = env.built_template_hotpatch_cache(&request.id); + + let mut command = Command::new("dx"); + if cache_dir.exists() { + let cache_dir = cache_dir.canonicalize()?; + command + .arg("hotpatch") + .arg("--web") + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("-aslr-reference") + .arg("0") + .arg("--json-output"); + } else { + if let Err(err) = std::fs::create_dir_all(&cache_dir) { + warn!("failed to create hotpatch cache dir {cache_dir:?}: {err}"); + } + let cache_dir = cache_dir.canonicalize()?; + command + .arg("build") + .arg("--web") + .arg("--fat-binary") + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("--json-output"); + } + + let mut child = start_limited_process(command, env)?; + + // If there is a artifacts cache, we can pipe it to dx for hot patching. + let artifacts_cache = cache_dir.join("artifacts.json"); + if artifacts_cache.exists() { + let artifacts_cache = std::fs::read_to_string(artifacts_cache)?; + if let Some(mut stdin) = child.stdin.take() { + use std::io::Write; + stdin.write_all(artifacts_cache.as_bytes())?; + stdin.flush()?; + } + } + let stderr = child.stderr.take().expect("dx stdout should exist"); let stdout = child.stdout.take().expect("dx stdout should exist"); let mut stdout_reader = BufReader::new(stdout).lines(); @@ -179,7 +216,7 @@ fn dx_build( while let Some(Ok(line)) = stdout_reader.next() { logs.push(line.clone()); - process_dx_message(request, line); + process_dx_message(env, request, line); } let status = child.wait(); // Check if the build was successful. @@ -232,7 +269,7 @@ fn set_dx_limits(process: &Child, env: &EnvVars) { /// Process a JSON-formatted message from the DX CLI, returning nothing on error. /// /// We don't care if this errors as it is human-readable output which the playground doesn't depend on for build status. -fn process_dx_message(request: &BuildRequest, message: String) { +fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) { // We parse the tracing json log and if it contains a json field, we parse that as StructuredOutput. let result = serde_json::from_str::(&message) .and_then(|m| serde_json::from_str::(&m.json)); @@ -269,6 +306,17 @@ fn process_dx_message(request: &BuildRequest, message: String) { .ws_msg_tx .send(BuildMessage::CargoDiagnostic(diagnostic)) } + StructuredOutput::BuildsFinished { client, .. } => { + let cache_dir = env.built_template_hotpatch_cache(&request.id); + let artifacts_cache = cache_dir.join("artifacts.json"); + if let Err(err) = std::fs::write( + &artifacts_cache, + serde_json::to_string(&client).unwrap_or_default(), + ) { + warn!("failed to write artifacts cache {artifacts_cache:?}: {err}"); + } + Ok(()) + } _ => Ok(()), }; } diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index 6f6c73faf7..239fa8becf 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -11,7 +11,7 @@ pub async fn check_cleanup(env: &EnvVars) -> Result<(), io::Error> { /// Check and cleanup the target dir if it exceeds the max size. async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { - let target_path = env.build_template_path.join("target"); + let target_path = env.target_dir(); let target_size = dir_size(&target_path).await?; if target_size > env.max_target_dir_size { From 340d7c0844f2ac1bc646e109fe6e67d4e4d7f469 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 2 Oct 2025 12:40:25 -0500 Subject: [PATCH 20/58] Implement hot patching --- Cargo.lock | 957 ++++--- Cargo.toml | 12 +- packages/playground/TODO.md | 13 + packages/playground/model/Cargo.toml | 1 + packages/playground/model/src/lib.rs | 16 +- packages/playground/playground/src/build.rs | 21 +- .../playground/src/components/panes.rs | 2 +- .../playground/playground/src/hotreload.rs | 32 +- packages/playground/playground/src/ws.rs | 27 +- packages/playground/server/Cargo.toml | 1 + packages/playground/server/src/app.rs | 7 +- .../playground/server/src/build/builder.rs | 214 +- packages/playground/server/src/build/mod.rs | 11 +- .../playground/server/src/build/watcher.rs | 46 +- packages/playground/server/src/main.rs | 4 +- packages/playground/server/src/share.rs | 6 +- packages/playground/server/src/ws.rs | 17 +- .../playground/server/template/Cargo.lock | 2473 +++++++++++++++++ .../playground/server/template/Cargo.toml | 26 + .../playground/server/template/Dioxus.toml | 23 + packages/playground/server/template/manual.sh | 2 + .../server/template/snippets/Cargo.toml | 25 +- .../playground/server/template/src/main.rs | 21 + 23 files changed, 3429 insertions(+), 528 deletions(-) create mode 100644 packages/playground/TODO.md create mode 100644 packages/playground/server/template/Cargo.lock create mode 100644 packages/playground/server/template/Cargo.toml create mode 100644 packages/playground/server/template/Dioxus.toml create mode 100644 packages/playground/server/template/manual.sh create mode 100644 packages/playground/server/template/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index af170f9245..bb3fae632c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "addr2line" -version = "0.24.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ "gimli", ] @@ -94,9 +94,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -203,9 +203,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.30" +version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" +checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" dependencies = [ "compression-codecs", "compression-core", @@ -365,11 +365,11 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" dependencies = [ - "axum-core 0.5.2", + "axum-core 0.5.5", "axum-macros", "base64 0.22.1", "bytes", @@ -387,15 +387,14 @@ dependencies = [ "multer", "percent-encoding", "pin-project-lite", - "rustversion", - "serde", + "serde_core", "serde_json", "serde_path_to_error", "serde_urlencoded", "sha1", "sync_wrapper", "tokio", - "tokio-tungstenite 0.26.2", + "tokio-tungstenite 0.28.0", "tower 0.5.2", "tower-layer", "tower-service", @@ -408,7 +407,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f08a543641554404b42acd0d2494df12ca2be034d7b8ee4dbbf7446f940a2ef" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", "client-ip", "serde", ] @@ -435,9 +434,9 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.2" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" dependencies = [ "bytes", "futures-core", @@ -446,7 +445,6 @@ dependencies = [ "http-body-util", "mime", "pin-project-lite", - "rustversion", "sync_wrapper", "tower-layer", "tower-service", @@ -466,9 +464,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.75" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ "addr2line", "cfg-if", @@ -476,7 +474,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-link 0.2.0", ] [[package]] @@ -644,9 +642,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1de8bc0aa9e9385ceb3bf0c152e3a9b9544f6c4a912c8ae504e80c1f0368603" +checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" dependencies = [ "serde_core", ] @@ -671,14 +669,14 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "cc" -version = "1.2.38" +version = "1.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f41ae168f955c12fb8960b057d70d0ca153fb83182b57d86380443527be7e9" +checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" dependencies = [ "find-msvc-tools", "jobserver", @@ -821,7 +819,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -877,9 +875,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" +checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" dependencies = [ "brotli", "compression-core", @@ -910,7 +908,7 @@ dependencies = [ "libc", "once_cell", "unicode-width", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -952,16 +950,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "console_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if", - "wasm-bindgen", -] - [[package]] name = "const-serialize" version = "0.7.0-rc.0" @@ -975,9 +963,9 @@ dependencies = [ [[package]] name = "const-serialize" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "const-serialize-macro 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "const-serialize-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "serde", ] @@ -995,7 +983,7 @@ dependencies = [ [[package]] name = "const-serialize-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "proc-macro2", "quote", @@ -1299,9 +1287,9 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] name = "deranged" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", ] @@ -1349,33 +1337,32 @@ dependencies = [ [[package]] name = "dioxus" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c5e29983134d7b38f2d4578afc649ce5df744d9a7e13a1b1a983376f1056f41" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-asset-resolver", + "dioxus-asset-resolver 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-cli-config", - "dioxus-config-macro", + "dioxus-config-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-config-macros", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-macro", - "dioxus-devtools", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-document", "dioxus-fullstack", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-liveview", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-liveview 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-logger", - "dioxus-router", + "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-server", "dioxus-signals", - "dioxus-ssr", + "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-stores", - "dioxus-web", + "dioxus-web 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus_server_macro", "manganis", "serde", - "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subsecond", "warnings", ] @@ -1389,14 +1376,27 @@ dependencies = [ "http", "infer", "jni", - "js-sys", "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "ndk", "ndk-context", "ndk-sys", "percent-encoding", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", +] + +[[package]] +name = "dioxus-asset-resolver" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "jni", + "js-sys", + "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "ndk", + "ndk-context", + "ndk-sys", + "thiserror 2.0.17", "wasm-bindgen-futures", "web-sys", ] @@ -1407,7 +1407,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e26d7984c2730639f0d83dcf727b66ec01acb9954fa8b62b9ee11138b033da88" dependencies = [ - "dioxus-rsx", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "prettyplease", "proc-macro2", "quote", @@ -1419,8 +1419,7 @@ dependencies = [ [[package]] name = "dioxus-cli-config" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cec511d8a05ed60071bb0088f07ec40325faf27a608fa19d65befdd842b57f" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "wasm-bindgen", ] @@ -1435,63 +1434,61 @@ dependencies = [ "quote", ] +[[package]] +name = "dioxus-config-macro" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "dioxus-config-macros" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349cae693022df3af125c9f794aef0ffec97f2e1d01c252d883149e7ca7a0324" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" [[package]] name = "dioxus-core" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b55eccaa5c4f35f1755ea18a5716fe8ecba60ff1f25c52be6ceda2e6a52eb6" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "const_format", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "longest-increasing-subsequence", "rustc-hash 2.1.1", "rustversion", "serde", "slab", "slotmap", - "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subsecond", "tracing", "warnings", ] [[package]] -name = "dioxus-core" +name = "dioxus-core-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9280f81c8d58863b3077f1b7ca097e2f2b28d30a5aa02a656fbf72b0aee1bd9f" dependencies = [ - "const_format", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", - "futures-channel", - "futures-util", - "generational-box 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", - "longest-increasing-subsequence", - "rustc-hash 2.1.1", - "rustversion", - "serde", - "slab", - "slotmap", - "subsecond 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", - "tracing", - "warnings", + "convert_case 0.8.0", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] name = "dioxus-core-macro" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9280f81c8d58863b3077f1b7ca097e2f2b28d30a5aa02a656fbf72b0aee1bd9f" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "convert_case 0.8.0", - "dioxus-rsx", + "dioxus-rsx 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "proc-macro2", "quote", "syn 2.0.106", @@ -1506,7 +1503,7 @@ checksum = "f0ef2a94b4ceb8f7a39f56a539d07e82b0358a49a0b95028ad48635975df29d7" [[package]] name = "dioxus-core-types" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" [[package]] name = "dioxus-desktop" @@ -1518,24 +1515,24 @@ dependencies = [ "base64 0.22.1", "cocoa", "core-foundation 0.10.1", - "dioxus-asset-resolver", + "dioxus-asset-resolver 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools", + "dioxus-core", + "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-document", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-interpreter-js", + "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "dunce", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "global-hotkey", "infer", "jni", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc", "muda", "ndk", @@ -1553,7 +1550,7 @@ dependencies = [ "slab", "subtle", "tao", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "tray-icon", @@ -1569,13 +1566,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60af4e129968ab1713471ed0b29c3eefa4e8e09252429487d7a581e93c7ecfe5" dependencies = [ "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-devtools-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "serde", "serde_json", - "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 2.0.16", + "subsecond", + "thiserror 2.0.17", + "tracing", + "tungstenite 0.27.0", + "warnings", +] + +[[package]] +name = "dioxus-devtools" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "dioxus-cli-config", + "dioxus-core", + "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-signals", + "serde", + "serde_json", + "subsecond", + "thiserror 2.0.17", "tracing", "tungstenite 0.27.0", "warnings", @@ -1587,19 +1602,19 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64274704b6a8d018112473cdce0b3db1dcccfa79bde445223592fe4e396ff5ef" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "serde", - "subsecond-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "subsecond-types", ] [[package]] name = "dioxus-devtools-types" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-core 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "dioxus-core", "serde", - "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "subsecond-types", ] [[package]] @@ -1682,14 +1697,14 @@ dependencies = [ "askama_escape 0.10.3", "async-recursion", "automod", - "axum 0.8.4", + "axum 0.8.6", "chrono", "dioxus", "dioxus-cli-config", "dioxus-desktop", - "dioxus-liveview", - "dioxus-ssr", - "dioxus-web", + "dioxus-liveview 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-ssr 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-web 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "form_urlencoded", "futures", "futures-util", @@ -1719,17 +1734,16 @@ dependencies = [ [[package]] name = "dioxus-document" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11c7f4ff62a842c026c74b9782dd9117a2310ec52de69d858a9e54b96b3bac15" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-macro", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy-js-bundle", + "generational-box", + "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "serde", "serde_json", "tracing", @@ -1738,37 +1752,36 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "cargo_metadata", - "manganis-core 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "serde", "serde_json", - "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "subsecond-types", ] [[package]] name = "dioxus-fullstack" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819981e8aa811d9b81ac3135a8a74db2f1fa7510473c3251f98eceb2c710632e" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "base64 0.22.1", "bytes", "ciborium", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools", + "dioxus-core", + "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-document", "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol", - "dioxus-history", - "dioxus-interpreter-js", + "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-server", - "dioxus-web", + "dioxus-web 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus_server_macro", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "http", "serde", "server_fn", @@ -1779,13 +1792,13 @@ dependencies = [ [[package]] name = "dioxus-fullstack-hooks" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5fad61b2821b8f26c8498834920d617449d0b866aaac01b95284237f76e9d5" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-fullstack-protocol", - "dioxus-history", - "dioxus-hooks", + "dioxus-core", + "dioxus-document", + "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", "futures-channel", "serde", @@ -1799,7 +1812,19 @@ checksum = "b2f266ad9e20be14b8899f2133dd942131f03e6749650e65e2aaec2c7f8a4bc1" dependencies = [ "base64 0.22.1", "ciborium", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", + "serde", + "tracing", +] + +[[package]] +name = "dioxus-fullstack-protocol" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "base64 0.22.1", + "ciborium", + "dioxus-core", "serde", "tracing", ] @@ -1810,7 +1835,16 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18e9e34323717a78ea3f8ba5072ff484744a656e8d422932c19937b67f45113e" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", + "tracing", +] + +[[package]] +name = "dioxus-history" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "dioxus-core", "tracing", ] @@ -1820,11 +1854,27 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab776b9a156765cc7dd7876891c98b9ab06b1f995d33ff169b06ef4f23cfd437" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", + "dioxus-signals", + "futures-channel", + "futures-util", + "generational-box", + "rustversion", + "slab", + "tracing", + "warnings", +] + +[[package]] +name = "dioxus-hooks" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "dioxus-core", "dioxus-signals", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "rustversion", "slab", "tracing", @@ -1838,18 +1888,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "073e5b69a7b66e9cbb49530df8c4cf86bf2aff3322ba86a3d722f9d58cd9c54b" dependencies = [ "async-trait", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-macro", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-hooks", - "dioxus-html-internal-macro", - "dioxus-rsx", + "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html-internal-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "enumset", "euclid", "futures-channel", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "keyboard-types", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustversion", + "serde", + "serde_json", + "serde_repr", + "tracing", +] + +[[package]] +name = "dioxus-html" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "async-trait", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html-internal-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "enumset", + "euclid", + "futures-channel", + "generational-box", + "keyboard-types", + "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "rustversion", "serde", "serde_json", @@ -1869,17 +1943,28 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "dioxus-html-internal-macro" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "convert_case 0.8.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "dioxus-interpreter-js" version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd2ef3fe9bddfcac6d2ccf123d4834b5c3d97e6f2be8fcbfc4943226d9d7d4fe" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "js-sys", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", @@ -1889,17 +1974,34 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-interpreter-js" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "dioxus-core", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "js-sys", + "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "rustc-hash 2.1.1", + "sledgehammer_bindgen", + "sledgehammer_utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "dioxus-isrg" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de299631d53fbde53d86609884a5b2bae65d9c1d86c78a79b7d2254b9ba1771" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "chrono", "http", "lru", "rustc-hash 2.1.1", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "walkdir", ] @@ -1910,22 +2012,49 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90ea4ac81b0c239f00c70a06d1433135babca3412817d4c21a1a188964e5a7f" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", + "dioxus-cli-config", + "dioxus-core", + "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-document", + "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel", + "futures-util", + "generational-box", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "slab", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + +[[package]] +name = "dioxus-liveview" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "axum 0.8.6", "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools", + "dioxus-core", + "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-document", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "rustc-hash 2.1.1", "serde", "serde_json", "slab", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -1935,10 +2064,8 @@ dependencies = [ [[package]] name = "dioxus-logger" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d39a7c4d1f848fa62d0e605aabce921cc8a95ccea3d17101a840d216471adb7" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "console_error_panic_hook", "dioxus-cli-config", "tracing", "tracing-subscriber", @@ -1952,12 +2079,12 @@ dependencies = [ "base64 0.22.1", "dioxus", "dioxus-autofmt", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools", + "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-document", - "dioxus-html", - "dioxus-rsx", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", "dioxus-sdk", @@ -1972,7 +2099,7 @@ dependencies = [ "serde-wasm-bindgen", "serde_json", "syn 2.0.106", - "thiserror 2.0.16", + "thiserror 2.0.17", "uuid", "wasm-bindgen", ] @@ -1984,13 +2111,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6260ba0131670716b7410bc6b2eba13cc7677ba133c9678b5508214a7a2a1794" dependencies = [ "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-macro", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-router-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-signals", + "percent-encoding", + "rustversion", + "tracing", + "url", +] + +[[package]] +name = "dioxus-router" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "dioxus-cli-config", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-fullstack-hooks", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-router-macro", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-router-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", "percent-encoding", "rustversion", @@ -2013,6 +2159,20 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "dioxus-router-macro" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "base16", + "digest", + "proc-macro2", + "quote", + "sha2", + "slab", + "syn 2.0.106", +] + [[package]] name = "dioxus-rsx" version = "0.7.0-rc.0" @@ -2025,15 +2185,26 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "dioxus-rsx" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.106", +] + [[package]] name = "dioxus-rsx-hotreload" version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c796e02557a4de1f4b4850e554b802b7bcce607103e0b1d5b4c530268791005e" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-rsx", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "internment", "proc-macro2", "proc-macro2-diagnostics", @@ -2050,8 +2221,8 @@ checksum = "1891c187301f3fed87ab2b18a58e473404bdb35c9fed6beadefcdd7801d96787" dependencies = [ "convert_case 0.8.0", "dioxus-autofmt", - "dioxus-html", - "dioxus-rsx", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "html_parser", "htmlentity", "proc-macro2", @@ -2074,7 +2245,7 @@ name = "dioxus-search" version = "0.1.0" dependencies = [ "bytes", - "dioxus-router", + "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-search-macro", "dioxus-search-shared", "getrandom 0.2.16", @@ -2100,7 +2271,7 @@ name = "dioxus-search-shared" version = "0.1.0" dependencies = [ "bytes", - "dioxus-router", + "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "getrandom 0.2.16", "log", "scraper", @@ -2115,33 +2286,32 @@ dependencies = [ [[package]] name = "dioxus-server" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1116ed485980f0df75d9251dd216e325e059d71fe1ef823ee967105aa4d4be48" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "async-trait", - "axum 0.8.4", + "axum 0.8.6", "base64 0.22.1", "bytes", "ciborium", "dashmap", "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-macro", - "dioxus-devtools", + "dioxus-core", + "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-document", "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", + "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-isrg", - "dioxus-router", + "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", - "dioxus-ssr", + "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "enumset", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "http", "hyper", "hyper-util", @@ -2150,8 +2320,8 @@ dependencies = [ "pin-project 1.1.10", "serde", "server_fn", - "subsecond 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 2.0.16", + "subsecond", + "thiserror 2.0.17", "tokio", "tokio-util", "tower 0.5.2", @@ -2165,13 +2335,12 @@ dependencies = [ [[package]] name = "dioxus-signals" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1d0e70a8da969c0404f5ef8cf6f47042bea55608b582079f3ea3d9fff46125c" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "parking_lot", "rustc-hash 2.1.1", "tracing", @@ -2185,18 +2354,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21c377da1f2ea708be1112dd61189d6dcd19c8db25208b750c3849f760fa854d" dependencies = [ "askama_escape 0.13.0", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 2.1.1", ] +[[package]] +name = "dioxus-ssr" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "askama_escape 0.13.0", + "dioxus-core", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "rustc-hash 2.1.1", +] + [[package]] name = "dioxus-stores" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5494e5aa7333f3be918741eeb6bfb4d1cbf28d25035a2a3c2c5bcebdc27b0b68" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-signals", "dioxus-stores-macro", ] @@ -2204,8 +2383,7 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecb7365b1a587a9f2340cf8f925a00b997d8d31b4ee25ecb21ca8bdf99c2c33" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2241,21 +2419,54 @@ checksum = "34eb4f341b0203f7b1fe1804d4561a19a399bf7fa4821a5b87cff5fd89d834bd" dependencies = [ "async-trait", "dioxus-cli-config", - "dioxus-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core", "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools", + "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-document", - "dioxus-fullstack-protocol", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", + "dioxus-fullstack-protocol 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "futures-channel", "futures-util", - "generational-box 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-hash 2.1.1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "dioxus-web" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +dependencies = [ + "async-trait", + "dioxus-cli-config", + "dioxus-core", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-document", + "dioxus-fullstack-hooks", + "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-signals", + "futures-channel", + "futures-util", + "generational-box", + "gloo-timers", + "js-sys", + "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "rustc-hash 2.1.1", "serde", "serde-wasm-bindgen", @@ -2272,7 +2483,7 @@ version = "0.7.0-rc.0" source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" dependencies = [ "dioxus", - "dioxus-config-macro", + "dioxus-config-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-desktop", "wasm-bindgen", "web-sys", @@ -2285,7 +2496,7 @@ dependencies = [ "askama_escape 0.10.3", "async-recursion", "automod", - "axum 0.8.4", + "axum 0.8.6", "chrono", "dioxus", "dioxus-docs-03", @@ -2297,7 +2508,7 @@ dependencies = [ "dioxus-docs-examples", "dioxus-playground", "dioxus-search", - "dioxus-web", + "dioxus-web 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "futures", "futures-util", "getrandom 0.2.16", @@ -2324,8 +2535,7 @@ dependencies = [ [[package]] name = "dioxus_server_macro" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a032e9eaa291ded578b6c368ba35dd18d052e1cbcf2395244e555edd1767e61" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "proc-macro2", "quote", @@ -2351,7 +2561,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -2574,7 +2784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -3010,17 +3220,7 @@ dependencies = [ [[package]] name = "generational-box" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb058e0358ff765e719ab3e61629c5090fedb6a6ccf66479de21440a33d7f084" -dependencies = [ - "parking_lot", - "tracing", -] - -[[package]] -name = "generational-box" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "parking_lot", "tracing", @@ -3105,9 +3305,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.31.1" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "gio" @@ -3199,7 +3399,7 @@ dependencies = [ "objc2", "objc2-app-kit", "once_cell", - "thiserror 2.0.16", + "thiserror 2.0.17", "windows-sys 0.59.0", "x11rb", "xkeysym", @@ -3692,7 +3892,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.0", + "windows-core 0.62.1", ] [[package]] @@ -3853,9 +4053,9 @@ dependencies = [ [[package]] name = "imgref" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0263a3d970d5c054ed9312c0057b4f3bde9c0b33836d3637361d4a9e6e7a408" +checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" [[package]] name = "include_dir" @@ -3989,6 +4189,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -4058,9 +4267,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.80" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -4107,6 +4316,11 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e22c4abc3d491546025db72681ed8b1ff0e6e77d67f196460179b027d591b6ff" +[[package]] +name = "lazy-js-bundle" +version = "0.7.0-rc.0" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" + [[package]] name = "lazy_static" version = "1.5.0" @@ -4327,11 +4541,10 @@ dependencies = [ [[package]] name = "manganis" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "105544bc1d466decccab19427eddb801b6e575bb4907410eb4fed604ed78d358" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "const-serialize 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "manganis-macro", ] @@ -4342,29 +4555,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71ef461824c58f3d260c1f548f7a8aee2e0b6b805a503d15f8535a3a6272d7" dependencies = [ "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-cli-config", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "serde", ] [[package]] name = "manganis-core" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ - "const-serialize 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "const-serialize 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-cli-config", + "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "serde", ] [[package]] name = "manganis-macro" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06115a15f5d7bf6fcfee1b6979155cc51ab21ce7f06d907f6435d24175778f9e" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "dunce", "macro-string", - "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "proc-macro2", "quote", "syn 2.0.106", @@ -4463,7 +4675,7 @@ dependencies = [ "anyhow", "convert_case 0.6.0", "dioxus-autofmt", - "dioxus-rsx", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "macro_state", "mdbook-shared", "once_cell", @@ -4500,7 +4712,7 @@ version = "0.1.0" dependencies = [ "anyhow", "convert_case 0.6.0", - "dioxus-rsx", + "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "macro_state", "mdbook-gen", "mdbook-shared", @@ -4532,9 +4744,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memfd" @@ -4610,7 +4822,8 @@ dependencies = [ name = "model" version = "0.1.0" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", + "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-document", "dioxus-dx-wire-format", "dioxus-logger", @@ -4619,7 +4832,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "uuid", ] @@ -4650,7 +4863,7 @@ dependencies = [ "objc2-foundation", "once_cell", "png 0.17.16", - "thiserror 2.0.16", + "thiserror 2.0.17", "windows-sys 0.60.2", ] @@ -4998,9 +5211,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.7" +version = "0.37.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" dependencies = [ "memchr", ] @@ -5172,7 +5385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" dependencies = [ "memchr", - "thiserror 2.0.16", + "thiserror 2.0.17", "ucd-trie", ] @@ -5646,7 +5859,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.106", @@ -5760,9 +5973,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -5897,7 +6110,7 @@ dependencies = [ "built", "cfg-if", "interpolate_name", - "itertools", + "itertools 0.12.1", "libc", "libfuzzer-sys", "log", @@ -5991,14 +6204,14 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] name = "regex" -version = "1.11.2" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" dependencies = [ "aho-corasick", "memchr", @@ -6008,9 +6221,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" dependencies = [ "aho-corasick", "memchr", @@ -6204,7 +6417,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -6231,9 +6444,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.6" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8572f3c2cb9934231157b45499fc41e1f58c589fdfb81a844ba873265e80f8eb" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -6267,7 +6480,7 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -6398,9 +6611,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", "serde_derive", @@ -6419,18 +6632,18 @@ dependencies = [ [[package]] name = "serde_core" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.226" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -6469,7 +6682,7 @@ checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ "percent-encoding", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ] [[package]] @@ -6508,11 +6721,12 @@ dependencies = [ name = "server" version = "0.1.0" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", "axum-client-ip", "console-subscriber", + "dashmap", "dioxus", - "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", + "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-dx-wire-format", "dioxus-logger", "example-projects", @@ -6524,7 +6738,7 @@ dependencies = [ "rustix", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tower 0.4.13", @@ -6542,7 +6756,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", "base64 0.22.1", "bytes", "const-str", @@ -6564,7 +6778,7 @@ dependencies = [ "serde_json", "serde_qs", "server_fn_macro_default", - "thiserror 2.0.16", + "thiserror 2.0.17", "throw_error", "tokio", "tokio-tungstenite 0.27.0", @@ -6917,8 +7131,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b14ed4d86ab065ffbfdb994fd3e44daf5244b02cb643bd52949d74b703f36605" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "js-sys", "libc", @@ -6926,44 +7139,17 @@ dependencies = [ "memfd", "memmap2", "serde", - "subsecond-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thiserror 2.0.16", + "subsecond-types", + "thiserror 2.0.17", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", ] -[[package]] -name = "subsecond" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#10912f475069e0c4e1dbbedb32f4ee16201d4c81" -dependencies = [ - "js-sys", - "libc", - "libloading 0.8.9", - "memfd", - "memmap2", - "serde", - "subsecond-types 0.7.0-rc.0 (git+https://github.com/DioxusLabs/dioxus)", - "thiserror 2.0.16", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "subsecond-types" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "275920a8a5634e47e12253971db85946798795bbe4d9dfc1debf23533d823983" -dependencies = [ - "serde", -] - [[package]] name = "subsecond-types" version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#2e7e0696a320a2a98a07e405603f59c8296b0b42" +source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" dependencies = [ "serde", ] @@ -7018,12 +7204,11 @@ dependencies = [ [[package]] name = "syntect" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +checksum = "656b45c05d95a5704399aeef6bd0ddec7b2b3531b7c9e900abbf7c4d2190c925" dependencies = [ "bincode", - "bitflags 1.3.2", "flate2", "fnv", "once_cell", @@ -7033,7 +7218,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.17", "walkdir", "yaml-rust", ] @@ -7150,7 +7335,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -7181,11 +7366,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ] [[package]] @@ -7201,9 +7386,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", @@ -7327,9 +7512,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f63835928ca123f1bef57abbcd23bb2ba0ac9ae1235f1e65bda0d06e7786bd" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -7348,26 +7533,26 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.26.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" +checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.26.2", + "tungstenite 0.27.0", ] [[package]] name = "tokio-tungstenite" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489a59b6730eda1b0171fcfda8b121f4bee2b35cba8645ca35c5f7ba3eb736c1" +checksum = "d25a406cddcc431a75d3d9afc6a7c0f7428d4891dd973e4d54c56b46127bf857" dependencies = [ "futures-util", "log", "tokio", - "tungstenite 0.27.0", + "tungstenite 0.28.0", ] [[package]] @@ -7537,7 +7722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203" dependencies = [ "async-trait", - "axum 0.8.4", + "axum 0.8.6", "base64 0.22.1", "bytes", "h2", @@ -7683,12 +7868,12 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44de9b94d849d3c46e06a883d72d408c2de6403367b39df2b1c9d9e7b6736fe6" dependencies = [ - "axum 0.8.4", + "axum 0.8.6", "forwarded-header-value", "governor", "http", "pin-project 1.1.10", - "thiserror 2.0.16", + "thiserror 2.0.17", "tonic 0.14.2", "tower 0.5.2", "tracing", @@ -7794,7 +7979,7 @@ dependencies = [ "objc2-foundation", "once_cell", "png 0.17.16", - "thiserror 2.0.16", + "thiserror 2.0.17", "windows-sys 0.59.0", ] @@ -7806,45 +7991,45 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.26.2" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" dependencies = [ "bytes", "data-encoding", "http", "httparse", "log", + "native-tls", "rand 0.9.2", + "rustls", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "utf-8", ] [[package]] name = "tungstenite" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" +checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", "http", "httparse", "log", - "native-tls", "rand 0.9.2", - "rustls", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "utf-8", ] [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ucd-trie" @@ -7928,7 +8113,7 @@ name = "use-mdbook" version = "0.1.0" dependencies = [ "dioxus", - "dioxus-router", + "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static", "mdbook-macro", "mdbook-shared", @@ -8079,9 +8264,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", @@ -8094,9 +8279,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", @@ -8108,9 +8293,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.53" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -8121,9 +8306,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8131,9 +8316,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", @@ -8144,9 +8329,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.103" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] @@ -8226,9 +8411,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.80" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -8335,7 +8520,7 @@ version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" dependencies = [ - "thiserror 2.0.16", + "thiserror 2.0.17", "windows", "windows-core 0.61.2", ] @@ -8368,7 +8553,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.0", + "windows-sys 0.61.1", ] [[package]] @@ -8414,9 +8599,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.62.0" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" dependencies = [ "windows-implement", "windows-interface", @@ -8438,9 +8623,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ "proc-macro2", "quote", @@ -8449,9 +8634,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" dependencies = [ "proc-macro2", "quote", @@ -8560,14 +8745,14 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.4", ] [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" dependencies = [ "windows-link 0.2.0", ] @@ -8605,11 +8790,11 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" dependencies = [ - "windows-link 0.1.3", + "windows-link 0.2.0", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", @@ -8631,9 +8816,9 @@ dependencies = [ [[package]] name = "windows-version" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e061eb0a22b4a1d778ad70f7575ec7845490abb35b08fa320df7895882cacb" +checksum = "700dad7c058606087f6fdc1f88da5841e06da40334413c6cd4367b25ef26d24e" dependencies = [ "windows-link 0.2.0", ] @@ -8838,7 +9023,7 @@ dependencies = [ "sha2", "soup3", "tao-macros", - "thiserror 2.0.16", + "thiserror 2.0.17", "url", "webkit2gtk", "webkit2gtk-sys", @@ -9041,9 +9226,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" diff --git a/Cargo.toml b/Cargo.toml index 38e7890c7b..1426991731 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,7 +79,7 @@ dioxus-rsx = "0.7.0-rc.0" dioxus-html = { version = "0.7.0-rc.0", default-features = false } dioxus-rsx-rosetta = "0.7.0-rc.0" dioxus-autofmt = "0.7.0-rc.0" -dioxus-dx-wire-format = { git = "https://github.com/DioxusLabs/dioxus" } +dioxus-dx-wire-format = "0.7.0-rc.0" dioxus-devtools-types = { git = "https://github.com/DioxusLabs/dioxus" } dioxus-logger = "0.7.0-rc.0" @@ -130,3 +130,13 @@ dioxus-sync = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-time = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-util = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } +generational-box = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/playground/TODO.md b/packages/playground/TODO.md new file mode 100644 index 0000000000..ff7d4075a3 --- /dev/null +++ b/packages/playground/TODO.md @@ -0,0 +1,13 @@ +# Bugs +- [x] Spamming rebuild breaks it - this is just rate limiting +- [x] Loading the built page is very very slow +- [x] Hot reloading only works after the first rebuild +- [x] Build errors don't show up +- [x] Switch to storage based clear instead of timeout +- [x] Investigate ws rate limiting. Can you send multiple build requests from the same websocket? +- [x] When the build changes stuff, it sometimes never sends the finished build message +- [x] Limit memory of dx + +# Features +- [ ] Get the component library working +- [x] Hot patching diff --git a/packages/playground/model/Cargo.toml b/packages/playground/model/Cargo.toml index c249232017..cc1fe0255d 100644 --- a/packages/playground/model/Cargo.toml +++ b/packages/playground/model/Cargo.toml @@ -19,6 +19,7 @@ axum = { workspace = true, features = ["ws"], optional = true } gloo-net = { workspace = true, optional = true } gloo-utils = { workspace = true, optional = true } dioxus-document = { workspace = true, optional = true } +dioxus-devtools.workspace = true [features] server = ["dep:dioxus-dx-wire-format", "dep:axum"] diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index a938d52e0c..7dc5ee39f1 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -1,3 +1,4 @@ +use dioxus_devtools::subsecond::JumpTable; use serde::{Deserialize, Serialize}; use std::error::Error; use std::string::FromUtf8Error; @@ -16,10 +17,21 @@ mod server; #[cfg(feature = "web")] mod web; +/// The result of a build +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum BuildResult { + Built(Uuid), + HotPatched(JumpTable), + Failed(String), +} + #[derive(Debug, Serialize, Deserialize)] pub enum SocketMessage { - BuildRequest(String), - BuildFinished(Result), + BuildRequest { + code: String, + previous_build_id: Option, + }, + BuildFinished(BuildResult), BuildStage(BuildStage), BuildDiagnostic(CargoDiagnostic), QueuePosition(usize), diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index ac3565ac68..a253287674 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -66,6 +66,7 @@ pub(crate) struct BuildState { stage: Signal, queue_position: Signal>, diagnostics: Signal>, + previous_build_id: Signal>, } impl BuildState { @@ -78,6 +79,7 @@ impl BuildState { }), queue_position: Signal::new(None), diagnostics: Signal::new(Vec::new()), + previous_build_id: Signal::new(None), } } @@ -86,6 +88,7 @@ impl BuildState { self.stage.set(BuildStage::NotStarted); self.queue_position.set(None); self.diagnostics.clear(); + self.previous_build_id.set(None); } /// Get the current stage. @@ -117,6 +120,11 @@ impl BuildState { pub fn push_diagnostic(&mut self, diagnostic: CargoDiagnostic) { self.diagnostics.push(diagnostic); } + + /// Get the previous build ID signal. + pub fn previous_build_id(&self) -> Signal> { + self.previous_build_id + } } /// Start a build and handle updating the build signals according to socket messages. @@ -125,16 +133,25 @@ pub async fn start_build( socket_url: String, code: String, ) -> Result { + let stage = build.stage(); // Reset build state - if build.stage().is_running() { + if stage.is_running() { return Err(AppError::BuildIsAlreadyRunning); } build.reset(); + if let Some(build_id) = stage.finished_id() { + build.previous_build_id().set(Some(build_id)); + } build.set_stage(BuildStage::Starting); // Send socket compile request let mut socket = ws::Socket::new(&socket_url)?; - socket.send(SocketMessage::BuildRequest(code)).await?; + socket + .send(SocketMessage::BuildRequest { + code, + previous_build_id: stage.finished_id(), + }) + .await?; // Handle socket messages loop { diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index 4f41f13e73..f8ca89b045 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -120,7 +120,7 @@ pub fn Panes( id: "dxp-panes-right", style: if let Some(val) = pane_right_width() { "width:{val}px;" }, - if build_stage.is_running() { + if build_stage.is_running() && false { Progress {} } else { // Viewport diff --git a/packages/playground/playground/src/hotreload.rs b/packages/playground/playground/src/hotreload.rs index f926a10283..95e7d259f7 100644 --- a/packages/playground/playground/src/hotreload.rs +++ b/packages/playground/playground/src/hotreload.rs @@ -1,9 +1,9 @@ //! Simplified hot reloading for a single main.rs file. +use ::dioxus_devtools::HotReloadMsg; use dioxus::{logger::tracing::error, prelude::*}; use dioxus_core::internal::{ HotReloadTemplateWithLocation, HotReloadedTemplate, TemplateGlobalKey, }; -use dioxus_devtools::HotReloadMsg; use dioxus_document::eval; use dioxus_html::HtmlCtx; use dioxus_rsx::CallBody; @@ -24,21 +24,8 @@ pub fn attempt_hot_reload(mut hot_reload: HotReload, new_code: &str) { jump_table: Default::default(), for_build_id: Default::default(), for_pid: Default::default(), - // unknown_files: Vec::new(), }; - - let e = eval( - r#" - const hrMsg = await dioxus.recv(); - const iframeElem = document.getElementById("dxp-iframe"); - const hrMsgJson = JSON.stringify(hrMsg); - - if (iframeElem) { - iframeElem.contentWindow.postMessage(hrMsgJson, "*"); - } - "#, - ); - _ = e.send(hr_msg); + send_hot_reload(hr_msg); } Err(HotReloadError::NeedsRebuild) => hot_reload.set_needs_rebuild(true), Err(e) => { @@ -48,6 +35,21 @@ pub fn attempt_hot_reload(mut hot_reload: HotReload, new_code: &str) { } } +pub fn send_hot_reload(hr_msg: HotReloadMsg) { + let e = eval( + r#" + const hrMsg = await dioxus.recv(); + const iframeElem = document.getElementById("dxp-iframe"); + const hrMsgJson = JSON.stringify(hrMsg); + + if (iframeElem) { + iframeElem.contentWindow.postMessage(hrMsgJson, "*"); + } + "#, + ); + _ = e.send(hr_msg); +} + #[derive(Clone, Copy)] pub struct HotReload { needs_rebuild: Signal, diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index 25d1db26ba..9f1b093d19 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -1,4 +1,6 @@ -use crate::{build::BuildStage, BuildState}; +use crate::{build::BuildStage, hotreload::send_hot_reload, BuildState}; +use dioxus::signals::ReadableExt; +use dioxus_devtools::HotReloadMsg; use futures::{SinkExt as _, StreamExt}; use gloo_net::websocket::futures::WebSocket; use model::*; @@ -42,8 +44,27 @@ pub fn handle_message(mut build: BuildState, message: SocketMessage) -> bool { match message { SocketMessage::BuildStage(stage) => build.set_stage(BuildStage::Building(stage)), SocketMessage::QueuePosition(position) => build.set_queue_position(Some(position)), - SocketMessage::BuildFinished(result) => { - build.set_stage(BuildStage::Finished(result)); + SocketMessage::BuildFinished(BuildResult::Failed(failure)) => { + build.set_stage(BuildStage::Finished(Err(failure))); + return true; + } + SocketMessage::BuildFinished(BuildResult::Built(id)) => { + build.set_stage(BuildStage::Finished(Ok(id))); + return true; + } + SocketMessage::BuildFinished(BuildResult::HotPatched(patch)) => { + // Get the iframe to apply the patch to. + send_hot_reload(HotReloadMsg { + templates: Default::default(), + assets: Default::default(), + ms_elapsed: Default::default(), + for_pid: Default::default(), + for_build_id: Some(0), + jump_table: Some(patch), + }); + if let Some(id) = build.previous_build_id().cloned() { + build.set_stage(BuildStage::Finished(Ok(id))); + } return true; } SocketMessage::BuildDiagnostic(diagnostic) => build.push_diagnostic(diagnostic), diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index d984d4cc8b..bda91a54bc 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -35,6 +35,7 @@ tracing-subscriber = "0.3.20" tower_governor = "0.8.0" governor = "0.10.1" rustix = { version = "1.1.2", features = ["process"] } +dashmap = "6.1.0" [features] tracing = ["tokio/tracing", "dep:console-subscriber"] diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index a989b9544c..3547ac997b 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -198,9 +198,6 @@ pub struct AppState { /// Prevents the server from shutting down during an active build. pub is_building: Arc, - /// A list of connected sockets by ip. Used to disallow extra socket connections. - pub _connected_sockets: Arc>>, - pub reqwest_client: reqwest::Client, pub build_govener: Arc< @@ -230,7 +227,7 @@ impl AppState { } let build_govener = Arc::new(RateLimiter::keyed( - Quota::with_period(Duration::from_secs(30)) + Quota::with_period(Duration::from_secs(5)) .unwrap() .allow_burst(NonZeroU32::new(2).unwrap()), )); @@ -240,7 +237,6 @@ impl AppState { build_queue_tx, last_request_time: Arc::new(Mutex::new(Instant::now())), is_building, - _connected_sockets: Arc::new(Mutex::new(Vec::new())), reqwest_client: reqwest::Client::new(), build_govener, }; @@ -254,6 +250,7 @@ impl AppState { let _ = state.build_queue_tx.send(BuildCommand::Start { request: BuildRequest { id: project.id(), + previous_build_id: None, project: project.clone(), ws_msg_tx: tx.clone(), }, diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 516e36bf7d..6b3dc6a47d 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -1,6 +1,7 @@ use super::{BuildError, BuildRequest}; use crate::app::EnvVars; use crate::build::{BuildMessage, CliMessage}; +use dioxus::subsecond::JumpTable; use dioxus_dx_wire_format::StructuredOutput; use dioxus_logger::tracing; use dioxus_logger::tracing::debug; @@ -8,14 +9,14 @@ use fs_extra::dir::CopyOptions; use model::{BuildStage, CargoDiagnostic}; use std::future::pending; use std::io::{BufRead, BufReader}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process::Stdio; use std::process::{Child, Command}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use tokio::fs; use tokio::task::JoinHandle; -use tracing::warn; +use tracing::{trace, warn}; const BUILD_ID_ID: &str = "{BUILD_ID}"; @@ -25,7 +26,7 @@ pub struct Builder { env: EnvVars, is_building: Arc, current_build: Option, - task: Option>>, + task: Option, BuildError>>>, } impl Builder { @@ -58,15 +59,16 @@ impl Builder { } /// Wait for the current build to finish. - pub async fn finished(&mut self) -> Result { + pub async fn finished(&mut self) -> Result<(BuildRequest, Option), BuildError> { // Ensure we don't poll a completed task. if let Some(task) = &mut self.task { if task.is_finished() { self.stop_current(); } else { // Make progress on the build task. - task.await??; - return self.current_build.take().ok_or(BuildError::NotStarted); + let response = task.await??; + let request = self.current_build.take().ok_or(BuildError::NotStarted)?; + return Ok((request, response)); } } pending().await @@ -84,14 +86,14 @@ impl Builder { } /// Run the steps to produce a build for a [`BuildRequest`] -async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { +async fn build(env: EnvVars, request: BuildRequest) -> Result, BuildError> { let built_path = &env.built_path; let template_path = &env.build_template_path; // If the project already exists, don't build it again. if std::fs::exists(built_path.join(request.id.to_string())).unwrap_or_default() { tracing::trace!("Skipping build for {request:?} since it already exists"); - return Ok(()); + return Ok(None); } // Check if we need to clean up old builds before starting a new one. @@ -100,16 +102,15 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result<(), BuildError> { } setup_template(&template_path, &request).await?; - tokio::task::spawn_blocking({ - let template_path = template_path.to_path_buf(); - let request = request.clone(); + let patch = tokio::task::spawn_blocking({ + let mut request = request.clone(); let env = env.clone(); - move || dx_build(&&request, &env) + move || dx_build(&mut request, &env) }) .await??; move_to_built(&template_path, &built_path, &request).await?; - Ok(()) + Ok(patch) } /// Resets the template with values for the next build. @@ -129,7 +130,10 @@ async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result< for (i, path) in snippets_from_copy.iter().enumerate() { let new_path = &snippets_to_copy[i]; let contents = fs::read_to_string(path).await?; - let contents = contents.replace(BUILD_ID_ID, &request.id.to_string()); + let contents = contents.replace( + BUILD_ID_ID, + &request.previous_build_id.unwrap_or(request.id).to_string(), + ); fs::write(new_path, contents).await?; } @@ -166,59 +170,104 @@ fn start_limited_process(mut command: Command, env: &EnvVars) -> Result Result<(), BuildError> { +fn dx_build(request: &mut BuildRequest, env: &EnvVars) -> Result, BuildError> { let cache_dir = env.built_template_hotpatch_cache(&request.id); + let previous_build_cache_dir = request + .previous_build_id + .map(|id| env.built_template_hotpatch_cache(&id)) + .filter(|p| p.exists()); - let mut command = Command::new("dx"); - if cache_dir.exists() { + // if there is a previous cache, try to use that to hot patch the build + if let Some(cache_dir) = previous_build_cache_dir { let cache_dir = cache_dir.canonicalize()?; - command - .arg("hotpatch") - .arg("--web") - .arg("--session-cache-dir") - .arg(cache_dir) - .arg("-aslr-reference") - .arg("0") - .arg("--json-output"); - } else { - if let Err(err) = std::fs::create_dir_all(&cache_dir) { - warn!("failed to create hotpatch cache dir {cache_dir:?}: {err}"); + let result = dx_patch_build(request, env, &cache_dir); + if let Ok(Some(patch)) = result { + return Ok(Some(patch)); + } else { + trace!("hotpatch build failed, falling back to full build"); } - let cache_dir = cache_dir.canonicalize()?; - command - .arg("build") - .arg("--web") - .arg("--fat-binary") - .arg("--session-cache-dir") - .arg(cache_dir) - .arg("--json-output"); } + // If the hot patch failed, remove the previous build id + request.previous_build_id.take(); + + // fallback to a full build + if let Err(err) = std::fs::create_dir_all(&cache_dir) { + warn!("failed to create hotpatch cache dir {cache_dir:?}: {err}"); + } + let cache_dir = cache_dir.canonicalize()?; + dx_full_build(request, env, &cache_dir).map(|_| None) +} + +fn dx_patch_build( + request: &mut BuildRequest, + env: &EnvVars, + cache_dir: &Path, +) -> Result, BuildError> { + tracing::info!("patching {:?}", request.previous_build_id); + let mut command = Command::new("dx"); + command + .arg("tools") + .arg("hotpatch") + .arg("--web") + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("--aslr-reference") + .arg("0") + .arg("--json-output"); + tracing::info!("running dx command: {:?}", command); + let mut child = start_limited_process(command, env)?; // If there is a artifacts cache, we can pipe it to dx for hot patching. let artifacts_cache = cache_dir.join("artifacts.json"); - if artifacts_cache.exists() { - let artifacts_cache = std::fs::read_to_string(artifacts_cache)?; - if let Some(mut stdin) = child.stdin.take() { - use std::io::Write; - stdin.write_all(artifacts_cache.as_bytes())?; - stdin.flush()?; - } + let artifacts_cache = std::fs::read_to_string(artifacts_cache)?; + if let Some(mut stdin) = child.stdin.take() { + use std::io::Write; + stdin.write_all(artifacts_cache.as_bytes())?; + stdin.flush()?; } - let stderr = child.stderr.take().expect("dx stdout should exist"); - let stdout = child.stdout.take().expect("dx stdout should exist"); - let mut stdout_reader = BufReader::new(stdout).lines(); - let mut stderr_reader = BufReader::new(stderr).lines(); + let (logs, patch) = process_build_messages(&mut child, env, request); - let mut logs = Vec::new(); + let status = child.wait(); - while let Some(Ok(line)) = stdout_reader.next() { - logs.push(line.clone()); - process_dx_message(env, request, line); + // Check if the build was successful. + let exit_code = status.map(|c| c.code()); + if let Ok(Some(code)) = exit_code { + if code == 0 { + return Ok(patch); + } else { + // Dump logs in debug. + for log in logs { + debug!("{log}"); + } + return Err(BuildError::DxFailed(Some(code))); + } } + + Err(BuildError::DxFailed(None)) +} + +fn dx_full_build( + request: &mut BuildRequest, + env: &EnvVars, + cache_dir: &Path, +) -> Result<(), BuildError> { + let mut command = Command::new("dx"); + command + .arg("build") + .arg("--web") + .arg("--fat-binary") + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("--json-output"); + let mut child = start_limited_process(command, env)?; + + let (logs, _patch) = process_build_messages(&mut child, env, request); + let status = child.wait(); + // Check if the build was successful. let exit_code = status.map(|c| c.code()); if let Ok(Some(code)) = exit_code { @@ -229,16 +278,38 @@ fn dx_build(request: &BuildRequest, env: &EnvVars) -> Result<(), BuildError> { for log in logs { debug!("{log}"); } - while let Some(Ok(line)) = stderr_reader.next() { - warn!("dx stderr: {line}"); - } - return Err(BuildError::DxFailed(Some(code))); } } Err(BuildError::DxFailed(None)) } +fn process_build_messages( + child: &mut Child, + env: &EnvVars, + request: &mut BuildRequest, +) -> (Vec, Option) { + let stderr = child.stderr.take().expect("dx stdout should exist"); + let stdout = child.stdout.take().expect("dx stdout should exist"); + let mut stdout_reader = BufReader::new(stdout).lines(); + let mut stderr_reader = BufReader::new(stderr).lines(); + + let mut logs = Vec::new(); + let mut patch = None; + + while let Some(Ok(line)) = stdout_reader.next() { + logs.push(line.clone()); + patch = patch.or(process_dx_message(env, request, line)); + } + + while let Some(Ok(line)) = stderr_reader.next() { + logs.push(line.clone()); + warn!("dx stderr: {line}"); + } + + (logs, patch) +} + #[allow(unused)] fn set_dx_limits(process: &Child, env: &EnvVars) { // TODO this isn't working, not sure why @@ -269,13 +340,17 @@ fn set_dx_limits(process: &Child, env: &EnvVars) { /// Process a JSON-formatted message from the DX CLI, returning nothing on error. /// /// We don't care if this errors as it is human-readable output which the playground doesn't depend on for build status. -fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) { +fn process_dx_message( + env: &EnvVars, + request: &mut BuildRequest, + message: String, +) -> Option { // We parse the tracing json log and if it contains a json field, we parse that as StructuredOutput. let result = serde_json::from_str::(&message) .and_then(|m| serde_json::from_str::(&m.json)); let Ok(output) = result else { - return; + return None; }; let _ = match output { @@ -285,12 +360,12 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) { } StructuredOutput::CargoOutput { message } => { let Ok(diagnostic) = CargoDiagnostic::try_from(message) else { - return; + return None; }; // Don't send any diagnostics for dependencies. if diagnostic.target_crate != Some(format!("play-{}", request.id)) { - return; + return None; } request @@ -299,7 +374,7 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) { } StructuredOutput::RustcOutput { message } => { let Ok(diagnostic) = CargoDiagnostic::try_from(message) else { - return; + return None; }; request @@ -317,8 +392,13 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) { } Ok(()) } + StructuredOutput::Hotpatch { jump_table, .. } => { + return Some(jump_table); + } _ => Ok(()), }; + + None } /// Moves the project built by `dx` to the final location for serving. @@ -327,7 +407,7 @@ async fn move_to_built( built_path: &Path, request: &BuildRequest, ) -> Result<(), BuildError> { - let id_string = request.id.to_string(); + let id_string = request.previous_build_id.unwrap_or(request.id).to_string(); // The path to the built project from DX let play_build_id = format!("play-{}", &id_string); @@ -345,14 +425,14 @@ async fn move_to_built( // We use `spawn_blocking` to batch call `std::fs` as recommended by Tokio. tokio::task::spawn_blocking::<_, Result<(), BuildError>>(move || { _ = std::fs::create_dir_all(&built_path); - // Rename to be the build id - let built_project = debug_web.join(&id_string); - std::fs::rename(&public_folder, &built_project)?; - // Copy to the built project folder for serving. let options = CopyOptions::new().overwrite(true); - fs_extra::dir::move_dir(&built_project, &built_path, &options)?; - std::fs::remove_dir_all(&built_project_parent)?; + fs_extra::dir::copy(&public_folder, &built_path, &options)?; + let out_dir = built_path.join(id_string); + // Remove the old output dir if it exists + _ = std::fs::remove_dir_all(&out_dir); + // rename to the build id + std::fs::rename(built_path.join("public"), out_dir)?; Ok(()) }) .await??; diff --git a/packages/playground/server/src/build/mod.rs b/packages/playground/server/src/build/mod.rs index 18bf6dd9a4..f8d7dddb7f 100644 --- a/packages/playground/server/src/build/mod.rs +++ b/packages/playground/server/src/build/mod.rs @@ -1,3 +1,4 @@ +use model::BuildResult; use model::CargoDiagnostic; use model::Project; use std::io; @@ -20,6 +21,7 @@ pub enum BuildCommand { #[derive(Debug, Clone)] pub struct BuildRequest { pub id: Uuid, + pub previous_build_id: Option, pub project: Project, pub ws_msg_tx: UnboundedSender, } @@ -29,10 +31,17 @@ pub struct BuildRequest { pub enum BuildMessage { Building(model::BuildStage), CargoDiagnostic(CargoDiagnostic), - Finished(Result), + Finished(BuildResult), QueuePosition(usize), } +impl BuildMessage { + /// Check if the build is done + pub fn is_done(&self) -> bool { + matches!(self, Self::Finished(_)) + } +} + /// The DX CLI serves parseable JSON output with the regular tracing message and a parseable "json" field. #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct CliMessage { diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index d69772652a..35d4154143 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -1,9 +1,10 @@ -use super::{builder::Builder, BuildCommand, BuildError, BuildMessage, BuildRequest}; +use super::{BuildCommand, BuildError, BuildMessage, BuildRequest, builder::Builder}; use crate::app::EnvVars; +use dioxus::subsecond::JumpTable; use std::{ collections::VecDeque, error::Error as _, - sync::{atomic::AtomicBool, Arc}, + sync::{Arc, atomic::AtomicBool}, }; use tokio::{ select, @@ -116,26 +117,33 @@ fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque fn handle_finished_build( builder: &mut Builder, pending_builds: &mut VecDeque, - build_result: Result, + build_result: Result<(BuildRequest, Option), BuildError>, ) { // Tell the socket the result of their build. - let _ = match build_result { - Ok(request) => { - dioxus::logger::tracing::trace!(request = ?request, "build finished"); - request - .ws_msg_tx - .send(BuildMessage::Finished(Ok(request.id))) - } - Err(e) => { - dioxus::logger::tracing::warn!(err = ?e, src = ?e.source(), "build failed"); - match builder.current_build() { - Some(request) => request - .ws_msg_tx - .send(BuildMessage::Finished(Err(e.to_string()))), - None => Ok(()), + let _ = + match build_result { + Ok((request, response)) => { + dioxus::logger::tracing::trace!(request = ?request, "build finished"); + if let Some(patch) = response { + request.ws_msg_tx.send(BuildMessage::Finished( + crate::build::BuildResult::HotPatched(patch), + )) + } else { + request.ws_msg_tx.send(BuildMessage::Finished( + crate::build::BuildResult::Built(request.id), + )) + } } - } - }; + Err(e) => { + dioxus::logger::tracing::warn!(err = ?e, src = ?e.source(), "build failed"); + match builder.current_build() { + Some(request) => request.ws_msg_tx.send(BuildMessage::Finished( + crate::build::BuildResult::Failed(e.to_string()), + )), + None => Ok(()), + } + } + }; // Start the next build. let next_request = pending_builds.pop_front(); diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 0b2e75dbd3..7280bdbebf 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -25,7 +25,7 @@ mod ws; /// Rate limiter configuration. /// How many requests each user should get within a time period. -const REQUESTS_PER_INTERVAL: u64 = 60; +const REQUESTS_PER_INTERVAL: u64 = 600; /// The period of time after the request limit resets. const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); @@ -78,7 +78,7 @@ async fn main() { .route("/{:id}", get(get_shared_project)); let app = Router::new() - .nest("/ws", Router::new().route("/", get(ws::ws_handler))) + .route("/ws", get(ws::ws_handler)) .nest("/built/{:build_id}", built_router) .nest("/shared", shared_router) .route( diff --git a/packages/playground/server/src/share.rs b/packages/playground/server/src/share.rs index a12554415a..5df639ac49 100644 --- a/packages/playground/server/src/share.rs +++ b/packages/playground/server/src/share.rs @@ -1,12 +1,12 @@ use crate::app::AppState; use axum::{ - extract::{Path, State}, Json, + extract::{Path, State}, }; use dioxus_logger::tracing::trace; use gists::{GistFile, NewGist}; -use model::api::{GetSharedProjectRes, ShareProjectReq, ShareProjectRes}; use model::AppError; +use model::api::{GetSharedProjectRes, ShareProjectReq, ShareProjectRes}; use std::collections::HashMap; const PRIMARY_GIST_FILE_NAME: &str = "dxp.rs"; @@ -54,7 +54,7 @@ pub async fn share_project( pub mod gists { use crate::app::AppState; use model::AppError; - use reqwest::{header, StatusCode}; + use reqwest::{StatusCode, header}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index 5cff677279..094f38ff79 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -17,6 +17,7 @@ use tokio::{ select, sync::mpsc::{self, UnboundedSender}, }; +use uuid::Uuid; /// Handle any pre-websocket processing. pub async fn ws_handler( @@ -50,7 +51,7 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { }; // Start a new build, stopping any existing ones. - if let SocketMessage::BuildRequest(code) = socket_msg { + if let SocketMessage::BuildRequest { code, previous_build_id } = socket_msg { if let Some(ref request) = current_build { let result = state.build_queue_tx.send(BuildCommand::Stop { id: request.id }); if result.is_err() { @@ -70,7 +71,7 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { tokio::time::sleep(wait_time).await; } - let request = start_build(&state, build_tx.clone(), code); + let request = start_build(&state, build_tx.clone(), code, previous_build_id); current_build = Some(request); } } @@ -84,7 +85,7 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { } // If the build finished, let's close this socket. - if let BuildMessage::Finished(_) = build_msg { + if build_msg.is_done() { current_build = None; let _ = socket_tx.close().await; break; @@ -104,14 +105,6 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { error!(build_id = ?request.id, "failed to send build stop signal for closed websocket"); } } - - // Drop the socket from our connected list. - // TODO: Convert this to a drop guard. - // let mut connected_sockets = state.connected_sockets.lock().await; - // let index = connected_sockets.iter().position(|x| **x == ip); - // if let Some(index) = index { - // connected_sockets.remove(index); - // } } /// Assembles the build request and sends it to the queue. @@ -119,10 +112,12 @@ fn start_build( state: &AppState, build_tx: UnboundedSender, code: String, + previous_build_id: Option, ) -> BuildRequest { let project = Project::new(code, None, None); let request = BuildRequest { id: project.id(), + previous_build_id, project, ws_msg_tx: build_tx, }; diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock new file mode 100644 index 0000000000..15c8e99662 --- /dev/null +++ b/packages/playground/server/template/Cargo.lock @@ -0,0 +1,2473 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "const-serialize" +version = "0.7.0-rc.0" +dependencies = [ + "const-serialize-macro", + "serde", +] + +[[package]] +name = "const-serialize-macro" +version = "0.7.0-rc.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "const-str" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451d0640545a0553814b4c646eb549343561618838e9b42495f466131fe3ad49" + +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dioxus" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-asset-resolver", + "dioxus-cli-config", + "dioxus-config-macro", + "dioxus-config-macros", + "dioxus-core", + "dioxus-core-macro", + "dioxus-document", + "dioxus-fullstack", + "dioxus-history", + "dioxus-hooks", + "dioxus-html", + "dioxus-logger", + "dioxus-router", + "dioxus-signals", + "dioxus-stores", + "dioxus-web", + "manganis", + "subsecond", + "warnings", +] + +[[package]] +name = "dioxus-asset-resolver" +version = "0.7.0-rc.0" +dependencies = [ + "jni", + "js-sys", + "manganis-core", + "ndk", + "ndk-context", + "ndk-sys", + "thiserror 2.0.17", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "dioxus-cli-config" +version = "0.7.0-rc.0" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "dioxus-config-macro" +version = "0.7.0-rc.0" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "dioxus-config-macros" +version = "0.7.0-rc.0" + +[[package]] +name = "dioxus-core" +version = "0.7.0-rc.0" +dependencies = [ + "const_format", + "dioxus-core-types", + "futures-channel", + "futures-util", + "generational-box", + "longest-increasing-subsequence", + "rustc-hash 2.1.1", + "rustversion", + "serde", + "slab", + "slotmap", + "subsecond", + "tracing", + "warnings", +] + +[[package]] +name = "dioxus-core-macro" +version = "0.7.0-rc.0" +dependencies = [ + "convert_case", + "dioxus-rsx", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dioxus-core-types" +version = "0.7.0-rc.0" + +[[package]] +name = "dioxus-devtools" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-cli-config", + "dioxus-core", + "dioxus-devtools-types", + "dioxus-signals", + "serde", + "serde_json", + "subsecond", + "thiserror 2.0.17", + "tracing", + "tungstenite", + "warnings", +] + +[[package]] +name = "dioxus-devtools-types" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "serde", + "subsecond-types", +] + +[[package]] +name = "dioxus-document" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "dioxus-core-macro", + "dioxus-core-types", + "dioxus-html", + "futures-channel", + "futures-util", + "generational-box", + "lazy-js-bundle", + "serde", + "serde_json", + "tracing", +] + +[[package]] +name = "dioxus-fullstack" +version = "0.7.0-rc.0" +dependencies = [ + "base64", + "bytes", + "ciborium", + "dioxus-core", + "dioxus-devtools", + "dioxus-document", + "dioxus-fullstack-hooks", + "dioxus-fullstack-protocol", + "dioxus-history", + "dioxus-web", + "dioxus_server_macro", + "futures-channel", + "futures-util", + "generational-box", + "http", + "serde", + "server_fn", + "tracing", + "web-sys", +] + +[[package]] +name = "dioxus-fullstack-hooks" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "dioxus-document", + "dioxus-fullstack-protocol", + "dioxus-history", + "dioxus-hooks", + "dioxus-signals", + "futures-channel", + "serde", +] + +[[package]] +name = "dioxus-fullstack-protocol" +version = "0.7.0-rc.0" +dependencies = [ + "base64", + "ciborium", + "dioxus-core", + "serde", + "tracing", +] + +[[package]] +name = "dioxus-history" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "tracing", +] + +[[package]] +name = "dioxus-hooks" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "dioxus-signals", + "futures-channel", + "futures-util", + "generational-box", + "rustversion", + "slab", + "tracing", + "warnings", +] + +[[package]] +name = "dioxus-html" +version = "0.7.0-rc.0" +dependencies = [ + "async-trait", + "dioxus-core", + "dioxus-core-macro", + "dioxus-core-types", + "dioxus-hooks", + "dioxus-html-internal-macro", + "enumset", + "euclid", + "futures-channel", + "generational-box", + "keyboard-types", + "lazy-js-bundle", + "rustversion", + "tracing", +] + +[[package]] +name = "dioxus-html-internal-macro" +version = "0.7.0-rc.0" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dioxus-interpreter-js" +version = "0.7.0-rc.0" +dependencies = [ + "js-sys", + "lazy-js-bundle", + "rustc-hash 2.1.1", + "sledgehammer_bindgen", + "sledgehammer_utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "dioxus-logger" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-cli-config", + "tracing", + "tracing-subscriber", + "tracing-wasm", +] + +[[package]] +name = "dioxus-router" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-cli-config", + "dioxus-core", + "dioxus-core-macro", + "dioxus-history", + "dioxus-hooks", + "dioxus-html", + "dioxus-router-macro", + "dioxus-signals", + "percent-encoding", + "rustversion", + "tracing", + "url", +] + +[[package]] +name = "dioxus-router-macro" +version = "0.7.0-rc.0" +dependencies = [ + "base16", + "digest", + "proc-macro2", + "quote", + "sha2", + "slab", + "syn", +] + +[[package]] +name = "dioxus-rsx" +version = "0.7.0-rc.0" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn", +] + +[[package]] +name = "dioxus-signals" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "futures-channel", + "futures-util", + "generational-box", + "parking_lot", + "rustc-hash 2.1.1", + "tracing", + "warnings", +] + +[[package]] +name = "dioxus-stores" +version = "0.7.0-rc.0" +dependencies = [ + "dioxus-core", + "dioxus-signals", + "dioxus-stores-macro", +] + +[[package]] +name = "dioxus-stores-macro" +version = "0.7.0-rc.0" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dioxus-web" +version = "0.7.0-rc.0" +dependencies = [ + "async-trait", + "dioxus-cli-config", + "dioxus-core", + "dioxus-core-types", + "dioxus-devtools", + "dioxus-document", + "dioxus-fullstack-hooks", + "dioxus-fullstack-protocol", + "dioxus-history", + "dioxus-html", + "dioxus-interpreter-js", + "dioxus-signals", + "futures-channel", + "futures-util", + "generational-box", + "gloo-timers", + "js-sys", + "lazy-js-bundle", + "rustc-hash 2.1.1", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "dioxus_server_macro" +version = "0.7.0-rc.0" +dependencies = [ + "proc-macro2", + "quote", + "server_fn_macro", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "enumset" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.1", +] + +[[package]] +name = "euclid" +version = "0.22.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generational-box" +version = "0.7.0-rc.0" +dependencies = [ + "parking_lot", + "tracing", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi", +] + +[[package]] +name = "gloo-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown 0.16.0", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "lazy-js-bundle" +version = "0.7.0-rc.0" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "manganis" +version = "0.7.0-rc.0" +dependencies = [ + "const-serialize", + "manganis-core", + "manganis-macro", +] + +[[package]] +name = "manganis-core" +version = "0.7.0-rc.0" +dependencies = [ + "const-serialize", + "dioxus-cli-config", + "dioxus-core-types", + "serde", +] + +[[package]] +name = "manganis-macro" +version = "0.7.0-rc.0" +dependencies = [ + "dunce", + "macro-string", + "manganis-core", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memfd" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" +dependencies = [ + "rustix", +] + +[[package]] +name = "memmap2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +dependencies = [ + "libc", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +version = "0.1.0" +dependencies = [ + "dioxus", + "wasm-bindgen", +] + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "quote" +version = "1.0.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex-automata" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.1", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" +dependencies = [ + "futures-core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_qs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" +dependencies = [ + "percent-encoding", + "serde", + "thiserror 2.0.17", +] + +[[package]] +name = "server_fn" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" +dependencies = [ + "base64", + "bytes", + "const-str", + "const_format", + "dashmap", + "futures", + "gloo-net", + "http", + "js-sys", + "pin-project-lite", + "rustc_version", + "rustversion", + "send_wrapper", + "serde", + "serde_json", + "serde_qs", + "server_fn_macro_default", + "thiserror 2.0.17", + "throw_error", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d530c872590473016016679c94e3bddf47372941fc924f687ffd11a1778a71" +dependencies = [ + "const_format", + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro_default" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca7abc92ed696648275ed9ff171131a83d571af11748593dc2e6eb6a4e22a5b9" +dependencies = [ + "server_fn_macro", + "syn", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "sledgehammer_bindgen" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e83e178d176459c92bc129cfd0958afac3ced925471b889b3a75546cfc4133" +dependencies = [ + "sledgehammer_bindgen_macro", + "wasm-bindgen", +] + +[[package]] +name = "sledgehammer_bindgen_macro" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "sledgehammer_utils" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "debdd4b83524961983cea3c55383b3910fd2f24fd13a188f5b091d2d504a61ae" +dependencies = [ + "rustc-hash 1.1.0", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subsecond" +version = "0.7.0-rc.0" +dependencies = [ + "js-sys", + "libc", + "libloading", + "memfd", + "memmap2", + "serde", + "subsecond-types", + "thiserror 2.0.17", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "subsecond-types" +version = "0.7.0-rc.0" +dependencies = [ + "serde", +] + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "throw_error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e42a6afdde94f3e656fae18f837cb9bbe500a5ac5de325b09f3ec05b9c28e3" +dependencies = [ + "pin-project-lite", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "toml_datetime" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.23.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +dependencies = [ + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "once_cell", + "regex-automata", + "sharded-slab", + "thread_local", + "tracing", + "tracing-core", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "tungstenite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "sha1", + "thiserror 2.0.17", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "warnings" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f68998838dab65727c9b30465595c6f7c953313559371ca8bf31759b3680ad" +dependencies = [ + "pin-project", + "tracing", + "warnings-macro", +] + +[[package]] +name = "warnings-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.1", +] + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "xxhash-rust" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml new file mode 100644 index 0000000000..acd6e4c58d --- /dev/null +++ b/packages/playground/server/template/Cargo.toml @@ -0,0 +1,26 @@ +# This excludes the template from the rest of the workspaces. +[workspace] + +[package] +name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +version = "0.1.0" +edition = "2024" + +[dependencies] +dioxus = { path = "../../../../../dioxus/packages/dioxus", features = ["web", "router", "launch", "logger", "lib"], default-features = false } +wasm-bindgen = "=0.2.100" + +[profile.dev.package."*"] +opt-level = 3 +debug = false +strip = true + +[profile.dev.package.dioxus-devtools] +opt-level = 3 +debug = true +strip = true + +[profile.dev.package.dioxus-web] +opt-level = 3 +debug = true +strip = true diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml new file mode 100644 index 0000000000..c190b50393 --- /dev/null +++ b/packages/playground/server/template/Dioxus.toml @@ -0,0 +1,23 @@ +[application] +name = "57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +default_platform = "web" +out_dir = "dist" +asset_dir = "public" +hot_reload = false + +[web.app] +base_path = "built/57d2f289-ba45-3195-ae0a-ea089d2f9bf8" + +title = "Dioxus Playground" +[web.watcher] +index_on_404 = true +watch_path = ["src", "examples"] +[web.resource] +style = [] +script = [] +[web.resource.dev] +script = [] +[application.plugins] +available = true +required = [] + diff --git a/packages/playground/server/template/manual.sh b/packages/playground/server/template/manual.sh new file mode 100644 index 0000000000..c99bfc4c2a --- /dev/null +++ b/packages/playground/server/template/manual.sh @@ -0,0 +1,2 @@ +"dx" "build" --fat-binary "--web" "--session-cache-dir" "/Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510" "--json-output" | tail -n 1 | jq .json -r | jq .BuildsFinished.client -c > /Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510/artifacts.json +clear && cat /Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510/artifacts.json | "dx" "tools" "hotpatch" "--web" "--session-cache-dir" "/Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510" "--aslr-reference" "0" "--json-output" diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index 7612819327..2571976e84 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -4,18 +4,23 @@ [package] name = "play-{BUILD_ID}" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] -dioxus = { version= "0.7.0-rc.0", features = ["web", "router"] } +dioxus = { version= "0.7.0-rc.0", features = ["web", "router", "launch", "logger", "lib"], default-features = false } +wasm-bindgen = "=0.2.100" -[profile.dev] -opt-level = 1 -debug-assertions = true -strip = true +[profile.dev.package."*"] +opt-level = 3 debug = false -incremental = true +strip = true -[profile.wasm-dev] -inherits = "dev" -opt-level = 1 +[profile.dev.package.dioxus-devtools] +opt-level = 3 +debug = true +strip = true + +[profile.dev.package.dioxus-web] +opt-level = 3 +debug = true +strip = true diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs new file mode 100644 index 0000000000..7959221635 --- /dev/null +++ b/packages/playground/server/template/src/main.rs @@ -0,0 +1,21 @@ +//! A basic counter example demonstrating signals, +//! event handlers, and basic rendering. + +use dioxus::prelude::*; + +fn main() { + dioxus::launch(App); +} + +#[component] +fn App() -> Element { + let mut count = use_signal(|| 0); + + rsx! { + p { "Count: {count*30}" } + div { style: "display: flex;", + button { onclick: move |_| count -= 1, "-" } + button { onclick: move |_| count += 1, "+" } + } + } +} From 4f50f3e7a52784b7b0a80d6b95e1c4a33b2d9a12 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 2 Oct 2025 12:57:31 -0500 Subject: [PATCH 21/58] fix dx version --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f3f286ba3a..5d137e9d49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /app FROM chef AS planner COPY . . -RUN cargo binstall dioxus-cli --root /.cargo --no-confirm --version 0.7.0-rc.0 +RUN cargo install dioxus-cli --git https://github.com/ealmloff/dioxus --branch cli-playground --root /.cargo RUN cargo chef prepare --recipe-path recipe.json --bin server # Builder From 3aff2b64188254aa624a009621f0a0768c85ba1b Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 2 Oct 2025 13:26:00 -0500 Subject: [PATCH 22/58] fix template dioxus dep --- packages/playground/server/src/build/cleanup.rs | 8 ++++++++ packages/playground/server/template/snippets/Cargo.toml | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index 239fa8becf..ee3bec9a6c 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -12,6 +12,10 @@ pub async fn check_cleanup(env: &EnvVars) -> Result<(), io::Error> { /// Check and cleanup the target dir if it exceeds the max size. async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { let target_path = env.target_dir(); + if !target_path.exists() { + return Ok(()); + } + let target_size = dir_size(&target_path).await?; if target_size > env.max_target_dir_size { @@ -23,6 +27,10 @@ async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { /// Check and cleanup any expired built projects async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { + if !env.built_path.exists() { + return Ok(()); + } + let mut dir = tokio::fs::read_dir(&env.built_path).await?; let mut dirs_with_size = Vec::new(); diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index 2571976e84..a8ab98dc1d 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -7,8 +7,9 @@ version = "0.1.0" edition = "2024" [dependencies] -dioxus = { version= "0.7.0-rc.0", features = ["web", "router", "launch", "logger", "lib"], default-features = false } +dioxus = { version = "0.7.0-rc.0", features = ["web", "router"] } wasm-bindgen = "=0.2.100" +web-sys = { version = "0.3", features = ["Location"] } [profile.dev.package."*"] opt-level = 3 From 4ef75b2c295f09e24e4b3a7f8709fba58e90f69c Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 6 Oct 2025 09:02:55 -0500 Subject: [PATCH 23/58] Add component library example --- packages/playground/TODO.md | 13 - .../example-projects/examples/calendar.rs | 53 ++++ packages/playground/model/src/server.rs | 2 + .../playground/src/components/header.rs | 45 +++- .../playground/src/components/panes.rs | 76 +----- packages/playground/server/src/app.rs | 6 +- .../playground/server/src/build/builder.rs | 28 ++ .../playground/server/src/build/watcher.rs | 3 + .../playground/server/template/.gitignore | 4 +- .../playground/server/template/Cargo.lock | 252 +++++++++++++++++- packages/playground/server/template/manual.sh | 2 - .../server/template/snippets/Cargo.toml | 17 +- .../server/template/snippets/Dioxus.toml | 3 +- .../playground/server/template/src/main.rs | 11 +- 14 files changed, 400 insertions(+), 115 deletions(-) delete mode 100644 packages/playground/TODO.md create mode 100644 packages/playground/example-projects/examples/calendar.rs delete mode 100644 packages/playground/server/template/manual.sh diff --git a/packages/playground/TODO.md b/packages/playground/TODO.md deleted file mode 100644 index ff7d4075a3..0000000000 --- a/packages/playground/TODO.md +++ /dev/null @@ -1,13 +0,0 @@ -# Bugs -- [x] Spamming rebuild breaks it - this is just rate limiting -- [x] Loading the built page is very very slow -- [x] Hot reloading only works after the first rebuild -- [x] Build errors don't show up -- [x] Switch to storage based clear instead of timeout -- [x] Investigate ws rate limiting. Can you send multiple build requests from the same websocket? -- [x] When the build changes stuff, it sometimes never sends the finished build message -- [x] Limit memory of dx - -# Features -- [ ] Get the component library working -- [x] Hot patching diff --git a/packages/playground/example-projects/examples/calendar.rs b/packages/playground/example-projects/examples/calendar.rs new file mode 100644 index 0000000000..149be2bcc1 --- /dev/null +++ b/packages/playground/example-projects/examples/calendar.rs @@ -0,0 +1,53 @@ +//! A simple example showcasing the dx-components library. + +mod components; + +use components::calendar::*; +use dioxus::prelude::*; +use time::{macros::date, Date, UtcDateTime}; + +static THEME: Asset = asset!("/assets/dx-components-theme.css"); + +fn main() { + dioxus::launch(App); +} + +#[component] +fn App() -> Element { + let mut selected_date = use_signal(|| None::); + let mut view_date = use_signal(|| UtcDateTime::now().date()); + rsx! { + document::Stylesheet { href: THEME } + div { + display: "flex", + align_items: "center", + justify_content: "center", + height: "100vh", + width: "100vw", + div { + width: "258px", + Calendar { + selected_date: selected_date(), + on_date_change: move |date| { + selected_date.set(date); + }, + view_date: view_date(), + on_view_change: move |new_view: Date| { + view_date.set(new_view); + }, + min_date: date!(1995 - 07 - 21), + max_date: date!(2035 - 09 - 11), + CalendarHeader { + CalendarNavigation { + CalendarPreviousMonthButton {} + CalendarSelectMonth {} + CalendarSelectYear {} + CalendarNextMonthButton {} + } + } + CalendarGrid {} + } + } + } + } +} diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 5e31910938..0bb8732756 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -69,6 +69,7 @@ impl TryFrom for CargoDiagnostic { let spans = diagnostic .spans .iter() + .filter(|s| s.file_name == "src/main.rs") .map(|s| CargoDiagnosticSpan { is_primary: s.is_primary, line_start: s.line_start, @@ -101,6 +102,7 @@ impl TryFrom for CargoDiagnostic { let spans = value .spans .iter() + .filter(|s| s.file_name == "src/main.rs") .map(|s| CargoDiagnosticSpan { is_primary: s.is_primary, line_start: s.line_start, diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 3919025506..7937f37a3f 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -1,4 +1,4 @@ -use crate::build::BuildState; +use crate::build::{BuildStage, BuildState}; use crate::components::icons::LoadingSpinner; use crate::share_code::copy_share_link; use crate::{Errors, PlaygroundUrls}; @@ -80,16 +80,7 @@ pub fn Header( }, if build.stage().is_running() { - LoadingSpinner {} - if let Some(pos) = build.queue_position() { - if pos == 0 { - "Building" - } else { - "#{pos}" - } - } else { - "Starting" - } + Progress {} } else { "Rebuild" } @@ -99,3 +90,35 @@ pub fn Header( } } } + +#[component] +fn Progress() -> Element { + let build = use_context::(); + + // Generate the loading message. + let message = use_memo(move || { + let compiling = build.stage().get_compiling_stage(); + if let Some((crates_compiled, total_crates, current_crate)) = compiling { + return format!("{crates_compiled}/{total_crates}"); + } + + match build.stage() { + BuildStage::NotStarted => "Waiting".to_string(), + BuildStage::Starting => "Starting".to_string(), + BuildStage::Waiting(time) => { + format!("Waiting {}s", time.as_secs()) + } + BuildStage::Building(build_stage) => match build_stage { + model::BuildStage::RunningBindgen => "Binding".to_string(), + model::BuildStage::Other => "Computing".to_string(), + model::BuildStage::Compiling { .. } => unreachable!(), + }, + BuildStage::Finished(_) => "Finished!".to_string(), + } + }); + + rsx! { + LoadingSpinner {} + "{message}" + } +} diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index f8ca89b045..7a0f9b4800 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -120,75 +120,21 @@ pub fn Panes( id: "dxp-panes-right", style: if let Some(val) = pane_right_width() { "width:{val}px;" }, - if build_stage.is_running() && false { - Progress {} - } else { - // Viewport - if build_stage.is_err() { - Logs {} - } else if let Some(url) = built_page_url() { - div { id: "dxp-viewport", - iframe { - id: "dxp-iframe", - src: "{url}", - pointer_events: if dragging() { "none" } else { "all" }, - } + // Viewport + if build_stage.is_err() { + Logs {} + } else if let Some(url) = built_page_url() { + div { id: "dxp-viewport", + iframe { + id: "dxp-iframe", + src: "{url}", + pointer_events: if dragging() { "none" } else { "all" }, } - } else { - p { "Click `Rebuild` to start a build!" } } + } else { + p { "Click `Rebuild` to start a build!" } } } } } } - -#[component] -fn Progress() -> Element { - let build = use_context::(); - - // Generate the loading message. - let message = use_memo(move || { - let compiling = build.stage().get_compiling_stage(); - if let Some((crates_compiled, total_crates, current_crate)) = compiling { - return format!("[{crates_compiled}/{total_crates}] Compiling {current_crate}"); - } - - match build.stage() { - BuildStage::NotStarted => "Build has not started.".to_string(), - BuildStage::Starting => "Starting build...".to_string(), - BuildStage::Waiting(time) => { - format!("Rate limited, waiting {} seconds...", time.as_secs()) - } - BuildStage::Building(build_stage) => match build_stage { - model::BuildStage::RunningBindgen => "Running wasm-bindgen...".to_string(), - model::BuildStage::Other => "Computing...".to_string(), - model::BuildStage::Compiling { .. } => unreachable!(), - }, - BuildStage::Finished(_) => "Finished!".to_string(), - } - }); - - // Determine the progress width. - let progress_width = use_memo(move || { - let stage = build.stage(); - let compiling = stage.get_compiling_stage(); - if let Some((crates_compiled, total_crates, _)) = compiling { - return (crates_compiled as f64 / total_crates as f64) * 100.0; - } - - match stage.is_running() { - true => 50.0, - false => 0.0, - } - }); - - rsx! { - div { id: "dxp-progress-container", - p { "{message}" } - div { id: "dxp-progress", - div { id: "dxp-bar", width: "{progress_width}%" } - } - } - } -} diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 3547ac997b..7cd97df4e8 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -215,11 +215,7 @@ impl AppState { let build_queue_tx = start_build_watcher(env.clone(), is_building.clone()); // Get prebuild arg - let prebuild = std::env::args() - .collect::>() - .get(1) - .map(|x| x == "--prebuild") - .unwrap_or(false); + let prebuild = std::env::args().any(|x| x == "--prebuild"); if prebuild { info!("server is prebuilding"); diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 6b3dc6a47d..0dc7cef0d9 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -39,6 +39,34 @@ impl Builder { } } + /// Make sure the components are initilized + pub fn update_component_library(&mut self) -> Result<(), BuildError> { + let update_status = Command::new("dx") + .arg("component") + .arg("update") + .current_dir(&self.env.build_template_path) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status()?; + if !update_status.success() { + return Err(BuildError::DxFailed(update_status.code())); + } + let status = Command::new("dx") + .arg("component") + .arg("add") + .arg("--all") + .arg("--force") + .current_dir(&self.env.build_template_path) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .status()?; + if !status.success() { + return Err(BuildError::DxFailed(status.code())); + } + + Ok(()) + } + /// Start a new build, cancelling any ongoing builds. pub fn start(&mut self, request: BuildRequest) { let _ = request.ws_msg_tx.send(BuildMessage::QueuePosition(0)); diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index 35d4154143..d0baf05356 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -24,6 +24,9 @@ pub fn start_build_watcher( tokio::spawn(async move { let mut builder = Builder::new(env, is_building); + if let Err(err) = builder.update_component_library() { + tracing::error!("failed to update component library: {err}"); + } let mut pending_builds = VecDeque::new(); loop { diff --git a/packages/playground/server/template/.gitignore b/packages/playground/server/template/.gitignore index 8f4cc2f477..4f5f03ebd1 100644 --- a/packages/playground/server/template/.gitignore +++ b/packages/playground/server/template/.gitignore @@ -4,4 +4,6 @@ Cargo.lock /Cargo.toml /Dioxus.toml /src/main.rs -.cargo \ No newline at end of file +/src/components +/assets +.cargo diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 15c8e99662..114c057c06 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.3" @@ -28,6 +43,21 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + [[package]] name = "base16" version = "0.2.1" @@ -119,6 +149,7 @@ dependencies = [ [[package]] name = "const-serialize" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "const-serialize-macro", "serde", @@ -127,6 +158,7 @@ dependencies = [ [[package]] name = "const-serialize-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "proc-macro2", "quote", @@ -253,6 +285,15 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -266,6 +307,7 @@ dependencies = [ [[package]] name = "dioxus" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -273,6 +315,7 @@ dependencies = [ "dioxus-config-macros", "dioxus-core", "dioxus-core-macro", + "dioxus-devtools", "dioxus-document", "dioxus-fullstack", "dioxus-history", @@ -291,6 +334,7 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "jni", "js-sys", @@ -306,6 +350,7 @@ dependencies = [ [[package]] name = "dioxus-cli-config" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "wasm-bindgen", ] @@ -313,6 +358,7 @@ dependencies = [ [[package]] name = "dioxus-config-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "proc-macro2", "quote", @@ -321,10 +367,12 @@ dependencies = [ [[package]] name = "dioxus-config-macros" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" [[package]] name = "dioxus-core" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "const_format", "dioxus-core-types", @@ -345,6 +393,7 @@ dependencies = [ [[package]] name = "dioxus-core-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "convert_case", "dioxus-rsx", @@ -356,10 +405,12 @@ dependencies = [ [[package]] name = "dioxus-core-types" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" [[package]] name = "dioxus-devtools" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -377,6 +428,7 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "serde", @@ -386,6 +438,7 @@ dependencies = [ [[package]] name = "dioxus-document" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -394,7 +447,7 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0", "serde", "serde_json", "tracing", @@ -403,6 +456,7 @@ dependencies = [ [[package]] name = "dioxus-fullstack" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "base64", "bytes", @@ -428,6 +482,7 @@ dependencies = [ [[package]] name = "dioxus-fullstack-hooks" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "dioxus-document", @@ -436,12 +491,14 @@ dependencies = [ "dioxus-hooks", "dioxus-signals", "futures-channel", + "futures-util", "serde", ] [[package]] name = "dioxus-fullstack-protocol" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "base64", "ciborium", @@ -453,6 +510,7 @@ dependencies = [ [[package]] name = "dioxus-history" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "tracing", @@ -461,6 +519,7 @@ dependencies = [ [[package]] name = "dioxus-hooks" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "dioxus-signals", @@ -476,6 +535,7 @@ dependencies = [ [[package]] name = "dioxus-html" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "async-trait", "dioxus-core", @@ -488,7 +548,7 @@ dependencies = [ "futures-channel", "generational-box", "keyboard-types", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0", "rustversion", "tracing", ] @@ -496,6 +556,7 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "convert_case", "proc-macro2", @@ -506,9 +567,10 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "js-sys", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0", "rustc-hash 2.1.1", "sledgehammer_bindgen", "sledgehammer_utils", @@ -520,6 +582,7 @@ dependencies = [ [[package]] name = "dioxus-logger" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-cli-config", "tracing", @@ -527,9 +590,22 @@ dependencies = [ "tracing-wasm", ] +[[package]] +name = "dioxus-primitives" +version = "0.0.1" +source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" +dependencies = [ + "dioxus", + "dioxus-time", + "lazy-js-bundle 0.6.2", + "time", + "tracing", +] + [[package]] name = "dioxus-router" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -548,6 +624,7 @@ dependencies = [ [[package]] name = "dioxus-router-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "base16", "digest", @@ -561,6 +638,7 @@ dependencies = [ [[package]] name = "dioxus-rsx" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -571,6 +649,7 @@ dependencies = [ [[package]] name = "dioxus-signals" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "futures-channel", @@ -585,6 +664,7 @@ dependencies = [ [[package]] name = "dioxus-stores" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dioxus-core", "dioxus-signals", @@ -594,6 +674,7 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "convert_case", "proc-macro2", @@ -601,9 +682,21 @@ dependencies = [ "syn", ] +[[package]] +name = "dioxus-time" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +dependencies = [ + "dioxus", + "futures", + "gloo-timers", + "tokio", +] + [[package]] name = "dioxus-web" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "async-trait", "dioxus-cli-config", @@ -622,7 +715,7 @@ dependencies = [ "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle", + "lazy-js-bundle 0.7.0-rc.0", "rustc-hash 2.1.1", "serde", "serde-wasm-bindgen", @@ -636,6 +729,7 @@ dependencies = [ [[package]] name = "dioxus_server_macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "proc-macro2", "quote", @@ -813,6 +907,7 @@ dependencies = [ [[package]] name = "generational-box" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "parking_lot", "tracing", @@ -837,9 +932,15 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi", + "wasi 0.14.7+wasi-0.2.4", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + [[package]] name = "gloo-net" version = "0.6.0" @@ -1048,6 +1149,17 @@ dependencies = [ "hashbrown 0.16.0", ] +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1095,9 +1207,16 @@ dependencies = [ "bitflags", ] +[[package]] +name = "lazy-js-bundle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" + [[package]] name = "lazy-js-bundle" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" [[package]] name = "lazy_static" @@ -1169,6 +1288,7 @@ dependencies = [ [[package]] name = "manganis" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "const-serialize", "manganis-core", @@ -1178,6 +1298,7 @@ dependencies = [ [[package]] name = "manganis-core" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -1188,6 +1309,7 @@ dependencies = [ [[package]] name = "manganis-macro" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "dunce", "macro-string", @@ -1230,6 +1352,26 @@ dependencies = [ "libc", ] +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + [[package]] name = "ndk" version = "0.9.0" @@ -1260,6 +1402,12 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -1291,6 +1439,15 @@ dependencies = [ "syn", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1359,11 +1516,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" version = "0.1.0" dependencies = [ "dioxus", + "dioxus-primitives", + "time", + "tracing", "wasm-bindgen", + "web-sys", ] [[package]] @@ -1375,6 +1536,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -1490,6 +1657,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + [[package]] name = "rustc-hash" version = "1.1.0" @@ -1780,6 +1953,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subsecond" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "js-sys", "libc", @@ -1797,6 +1971,7 @@ dependencies = [ [[package]] name = "subsecond-types" version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" dependencies = [ "serde", ] @@ -1881,6 +2056,37 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "js-sys", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" version = "0.8.1" @@ -1891,6 +2097,20 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", +] + [[package]] name = "toml_datetime" version = "0.7.2" @@ -2081,6 +2301,12 @@ dependencies = [ "syn", ] +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + [[package]] name = "wasi" version = "0.14.7+wasi-0.2.4" @@ -2217,6 +2443,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.61.1" @@ -2471,3 +2706,8 @@ dependencies = [ "quote", "syn", ] + +[[patch.unused]] +name = "dioxus-dx-wire-format" +version = "0.7.0-rc.0" +source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" diff --git a/packages/playground/server/template/manual.sh b/packages/playground/server/template/manual.sh deleted file mode 100644 index c99bfc4c2a..0000000000 --- a/packages/playground/server/template/manual.sh +++ /dev/null @@ -1,2 +0,0 @@ -"dx" "build" --fat-binary "--web" "--session-cache-dir" "/Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510" "--json-output" | tail -n 1 | jq .json -r | jq .BuildsFinished.client -c > /Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510/artifacts.json -clear && cat /Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510/artifacts.json | "dx" "tools" "hotpatch" "--web" "--session-cache-dir" "/Users/evanalmloff/Desktop/Github/docsite/packages/playground/server/template/target/hotpatch_cache/015cef34-f8d3-3b3f-913a-d74f0e3ac510" "--aslr-reference" "0" "--json-output" diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index a8ab98dc1d..cfe5b85452 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -7,7 +7,10 @@ version = "0.1.0" edition = "2024" [dependencies] -dioxus = { version = "0.7.0-rc.0", features = ["web", "router"] } +dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } +time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } +tracing = "0.1.41" wasm-bindgen = "=0.2.100" web-sys = { version = "0.3", features = ["Location"] } @@ -25,3 +28,15 @@ strip = true opt-level = 3 debug = true strip = true + +[patch.crates-io] +dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } +generational-box = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/playground/server/template/snippets/Dioxus.toml b/packages/playground/server/template/snippets/Dioxus.toml index 0808933fd0..e06d2f38fb 100644 --- a/packages/playground/server/template/snippets/Dioxus.toml +++ b/packages/playground/server/template/snippets/Dioxus.toml @@ -2,7 +2,7 @@ name = "{BUILD_ID}" default_platform = "web" out_dir = "dist" -asset_dir = "public" +asset_dir = "assets" hot_reload = false [web.app] @@ -20,4 +20,3 @@ script = [] [application.plugins] available = true required = [] - diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 7959221635..c65f7ffbcc 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -1,5 +1,4 @@ -//! A basic counter example demonstrating signals, -//! event handlers, and basic rendering. +//! The simplest Dioxus app use dioxus::prelude::*; @@ -9,13 +8,7 @@ fn main() { #[component] fn App() -> Element { - let mut count = use_signal(|| 0); - rsx! { - p { "Count: {count*30}" } - div { style: "display: flex;", - button { onclick: move |_| count -= 1, "-" } - button { onclick: move |_| count += 1, "+" } - } + div { "Build stuff!" } } } From 8af34086ac08a58b296502a73642fdcef0c46b19 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 6 Oct 2025 09:32:35 -0500 Subject: [PATCH 24/58] fix full rebuilds --- .../calendar.rs | 0 .../counter.rs | 0 .../welcome.rs | 0 .../playground/example-projects/src/lib.rs | 3 +- .../playground/server/src/build/builder.rs | 71 ++++++++++--------- .../playground/server/template/src/main.rs | 2 +- 6 files changed, 41 insertions(+), 35 deletions(-) rename packages/playground/example-projects/{examples => playground-examples}/calendar.rs (100%) rename packages/playground/example-projects/{examples => playground-examples}/counter.rs (100%) rename packages/playground/example-projects/{examples => playground-examples}/welcome.rs (100%) diff --git a/packages/playground/example-projects/examples/calendar.rs b/packages/playground/example-projects/playground-examples/calendar.rs similarity index 100% rename from packages/playground/example-projects/examples/calendar.rs rename to packages/playground/example-projects/playground-examples/calendar.rs diff --git a/packages/playground/example-projects/examples/counter.rs b/packages/playground/example-projects/playground-examples/counter.rs similarity index 100% rename from packages/playground/example-projects/examples/counter.rs rename to packages/playground/example-projects/playground-examples/counter.rs diff --git a/packages/playground/example-projects/examples/welcome.rs b/packages/playground/example-projects/playground-examples/welcome.rs similarity index 100% rename from packages/playground/example-projects/examples/welcome.rs rename to packages/playground/example-projects/playground-examples/welcome.rs diff --git a/packages/playground/example-projects/src/lib.rs b/packages/playground/example-projects/src/lib.rs index 4141bd8ad8..dd03d7276b 100644 --- a/packages/playground/example-projects/src/lib.rs +++ b/packages/playground/example-projects/src/lib.rs @@ -2,7 +2,8 @@ use include_dir::DirEntry; use model::Project; use once_cell::sync::Lazy; -static EXAMPLES: include_dir::Dir = include_dir::include_dir!("$CARGO_MANIFEST_DIR/examples"); +static EXAMPLES: include_dir::Dir = + include_dir::include_dir!("$CARGO_MANIFEST_DIR/playground-examples"); pub fn get_welcome_project() -> Project { get_example_projects() diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 0dc7cef0d9..4723fdd49a 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -129,20 +129,18 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result, warn!("failed to clean built projects: {e}"); } - setup_template(&template_path, &request).await?; - let patch = tokio::task::spawn_blocking({ - let mut request = request.clone(); - let env = env.clone(); - move || dx_build(&mut request, &env) - }) - .await??; - move_to_built(&template_path, &built_path, &request).await?; + let patch = dx_build(&request, &env).await?; + move_to_built(&template_path, &built_path, &request, patch.is_some()).await?; Ok(patch) } /// Resets the template with values for the next build. -async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result<(), BuildError> { +async fn setup_template( + template_path: &Path, + request: &BuildRequest, + patch: bool, +) -> Result<(), BuildError> { let snippets_from_copy = [ template_path.join("snippets/Cargo.toml"), template_path.join("snippets/Dioxus.toml"), @@ -160,7 +158,11 @@ async fn setup_template(template_path: &Path, request: &BuildRequest) -> Result< let contents = fs::read_to_string(path).await?; let contents = contents.replace( BUILD_ID_ID, - &request.previous_build_id.unwrap_or(request.id).to_string(), + &request + .previous_build_id + .filter(|_| patch) + .unwrap_or(request.id) + .to_string(), ); fs::write(new_path, contents).await?; } @@ -198,8 +200,7 @@ fn start_limited_process(mut command: Command, env: &EnvVars) -> Result Result, BuildError> { - let cache_dir = env.built_template_hotpatch_cache(&request.id); +async fn dx_build(request: &BuildRequest, env: &EnvVars) -> Result, BuildError> { let previous_build_cache_dir = request .previous_build_id .map(|id| env.built_template_hotpatch_cache(&id)) @@ -208,7 +209,7 @@ fn dx_build(request: &mut BuildRequest, env: &EnvVars) -> Result Result Result, BuildError> { tracing::info!("patching {:?}", request.previous_build_id); + setup_template(&env.build_template_path, &request, true).await?; let mut command = Command::new("dx"); command .arg("tools") @@ -258,11 +259,11 @@ fn dx_patch_build( let (logs, patch) = process_build_messages(&mut child, env, request); - let status = child.wait(); + let status = tokio::task::spawn_blocking(move || child.wait()).await; // Check if the build was successful. - let exit_code = status.map(|c| c.code()); - if let Ok(Some(code)) = exit_code { + let exit_code = status.map(|r| r.map(|c| c.code())); + if let Ok(Ok(Some(code))) = exit_code { if code == 0 { return Ok(patch); } else { @@ -277,11 +278,13 @@ fn dx_patch_build( Err(BuildError::DxFailed(None)) } -fn dx_full_build( - request: &mut BuildRequest, +async fn dx_full_build( + request: &BuildRequest, env: &EnvVars, cache_dir: &Path, ) -> Result<(), BuildError> { + setup_template(&env.build_template_path, &request, false).await?; + let mut command = Command::new("dx"); command .arg("build") @@ -290,15 +293,16 @@ fn dx_full_build( .arg("--session-cache-dir") .arg(cache_dir) .arg("--json-output"); + tracing::info!("running dx command: {:?}", command); let mut child = start_limited_process(command, env)?; let (logs, _patch) = process_build_messages(&mut child, env, request); - let status = child.wait(); + let status = tokio::task::spawn_blocking(move || child.wait()).await; // Check if the build was successful. - let exit_code = status.map(|c| c.code()); - if let Ok(Some(code)) = exit_code { + let exit_code = status.map(|r| r.map(|c| c.code())); + if let Ok(Ok(Some(code))) = exit_code { if code == 0 { return Ok(()); } else { @@ -315,7 +319,7 @@ fn dx_full_build( fn process_build_messages( child: &mut Child, env: &EnvVars, - request: &mut BuildRequest, + request: &BuildRequest, ) -> (Vec, Option) { let stderr = child.stderr.take().expect("dx stdout should exist"); let stdout = child.stdout.take().expect("dx stdout should exist"); @@ -368,11 +372,7 @@ fn set_dx_limits(process: &Child, env: &EnvVars) { /// Process a JSON-formatted message from the DX CLI, returning nothing on error. /// /// We don't care if this errors as it is human-readable output which the playground doesn't depend on for build status. -fn process_dx_message( - env: &EnvVars, - request: &mut BuildRequest, - message: String, -) -> Option { +fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> Option { // We parse the tracing json log and if it contains a json field, we parse that as StructuredOutput. let result = serde_json::from_str::(&message) .and_then(|m| serde_json::from_str::(&m.json)); @@ -434,8 +434,13 @@ async fn move_to_built( template_path: &Path, built_path: &Path, request: &BuildRequest, + patched: bool, ) -> Result<(), BuildError> { - let id_string = request.previous_build_id.unwrap_or(request.id).to_string(); + let id_string = request + .previous_build_id + .filter(|_| patched) + .unwrap_or(request.id) + .to_string(); // The path to the built project from DX let play_build_id = format!("play-{}", &id_string); diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index c65f7ffbcc..2a4f50e2fb 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -9,6 +9,6 @@ fn main() { #[component] fn App() -> Element { rsx! { - div { "Build stuff!" } + div { "Build" } } } From 275368f7584ef2c7dbde388354f44a29f2807760 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 7 Oct 2025 11:59:30 -0500 Subject: [PATCH 25/58] use the component library for the modal --- Cargo.lock | 19 +++ packages/playground/playground/Cargo.toml | 1 + .../playground/assets/dx-components-theme.css | 83 ++++++++++ .../playground/src/components/icons.rs | 1 + .../playground/src/components/modal.rs | 43 ++--- .../src/dx_components/button/component.rs | 62 +++++++ .../src/dx_components/button/mod.rs | 2 + .../src/dx_components/button/style.css | 54 +++++++ .../src/dx_components/dialog/component.rs | 52 ++++++ .../src/dx_components/dialog/mod.rs | 2 + .../src/dx_components/dialog/style.css | 104 ++++++++++++ .../playground/src/dx_components/mod.rs | 4 + .../src/dx_components/select/component.rs | 116 +++++++++++++ .../src/dx_components/select/mod.rs | 2 + .../src/dx_components/select/style.css | 153 ++++++++++++++++++ packages/playground/playground/src/lib.rs | 3 + .../playground/server/template/Cargo.lock | 2 +- .../playground/server/template/Cargo.toml | 20 ++- .../playground/server/template/Dioxus.toml | 7 +- .../playground/server/template/src/main.rs | 11 +- 20 files changed, 705 insertions(+), 36 deletions(-) create mode 100644 packages/playground/playground/assets/dx-components-theme.css create mode 100644 packages/playground/playground/src/dx_components/button/component.rs create mode 100644 packages/playground/playground/src/dx_components/button/mod.rs create mode 100644 packages/playground/playground/src/dx_components/button/style.css create mode 100644 packages/playground/playground/src/dx_components/dialog/component.rs create mode 100644 packages/playground/playground/src/dx_components/dialog/mod.rs create mode 100644 packages/playground/playground/src/dx_components/dialog/style.css create mode 100644 packages/playground/playground/src/dx_components/mod.rs create mode 100644 packages/playground/playground/src/dx_components/select/component.rs create mode 100644 packages/playground/playground/src/dx_components/select/mod.rs create mode 100644 packages/playground/playground/src/dx_components/select/style.css diff --git a/Cargo.lock b/Cargo.lock index bb3fae632c..bdcefa22d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2084,6 +2084,7 @@ dependencies = [ "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-document", "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-primitives", "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", @@ -2104,6 +2105,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "dioxus-primitives" +version = "0.0.1" +source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" +dependencies = [ + "dioxus", + "dioxus-time", + "lazy-js-bundle 0.6.2", + "time", + "tracing", +] + [[package]] name = "dioxus-router" version = "0.7.0-rc.0" @@ -4310,6 +4323,12 @@ dependencies = [ "selectors 0.24.0", ] +[[package]] +name = "lazy-js-bundle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" + [[package]] name = "lazy-js-bundle" version = "0.7.0-rc.0" diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index 622fb1c88e..c65e21eeae 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -40,6 +40,7 @@ proc-macro2 = "1.0.89" example-projects = { workspace = true } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false } [target.'cfg(target_arch = "wasm32")'.dependencies] # dioxus-sdk = { workspace = true, default-features = false, features = ["system_theme", "window_size", "timing",] } diff --git a/packages/playground/playground/assets/dx-components-theme.css b/packages/playground/playground/assets/dx-components-theme.css new file mode 100644 index 0000000000..7c61d73540 --- /dev/null +++ b/packages/playground/playground/assets/dx-components-theme.css @@ -0,0 +1,83 @@ +/* This file contains the global styles for the styled dioxus components. You only + * need to import this file once in your project root. + */ +@import url("https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"); + +body { + padding: 0; + margin: 0; + background-color: var(--primary-color); + color: var(--secondary-color-4); + font-family: Inter, sans-serif; + font-optical-sizing: auto; + font-style: normal; + font-weight: 400; +} + +@media (prefers-color-scheme: dark) { + :root { + --dark: initial; + --light: ; + } +} + +@media (prefers-color-scheme: light) { + :root { + --dark: ; + --light: initial; + } +} + +:root { + /* Primary colors */ + --primary-color: var(--dark, #000) var(--light, #fff); + --primary-color-1: var(--dark, #0e0e0e) var(--light, #fbfbfb); + --primary-color-2: var(--dark, #0a0a0a) var(--light, #fff); + --primary-color-3: var(--dark, #141313) var(--light, #f8f8f8); + --primary-color-4: var(--dark, #1a1a1a) var(--light, #f8f8f8); + --primary-color-5: var(--dark, #262626) var(--light, #f5f5f5); + --primary-color-6: var(--dark, #232323) var(--light, #e5e5e5); + --primary-color-7: var(--dark, #3e3e3e) var(--light, #b0b0b0); + + /* Secondary colors */ + --secondary-color: var(--dark, #fff) var(--light, #000); + --secondary-color-1: var(--dark, #fafafa) var(--light, #000); + --secondary-color-2: var(--dark, #e6e6e6) var(--light, #0d0d0d); + --secondary-color-3: var(--dark, #dcdcdc) var(--light, #2b2b2b); + --secondary-color-4: var(--dark, #d4d4d4) var(--light, #111); + --secondary-color-5: var(--dark, #a1a1a1) var(--light, #848484); + --secondary-color-6: var(--dark, #5d5d5d) var(--light, #d0d0d0); + + /* Highlight colors */ + --focused-border-color: var(--dark, #2b7fff) var(--light, #2b7fff); + --primary-success-color: var(--dark, #02271c) var(--light, #ecfdf5); + --secondary-success-color: var(--dark, #b6fae3) var(--light, #10b981); + --primary-warning-color: var(--dark, #342203) var(--light, #fffbeb); + --secondary-warning-color: var(--dark, #feeac7) var(--light, #f59e0b); + --primary-error-color: var(--dark, #a22e2e) var(--light, #dc2626); + --secondary-error-color: var(--dark, #9b1c1c) var(--light, #ef4444); + --contrast-error-color: var(--dark, var(--secondary-color-3)) + var(--light, var(--primary-color)); + --primary-info-color: var(--dark, var(--primary-color-5)) + var(--light, var(--primary-color)); + --secondary-info-color: var(--dark, var(--primary-color-7)) + var(--light, var(--secondary-color-3)); +} + +/* Modern browsers with `scrollbar-*` support */ +@supports (scrollbar-width: auto) { + :not(:hover) { + scrollbar-color: rgb(0 0 0 / 0%) rgb(0 0 0 / 0%); + } + + :hover { + scrollbar-color: var(--secondary-color-2) rgba(0, 0, 0, 0); + } +} + +/* Legacy browsers with `::-webkit-scrollbar-*` support */ +@supports selector(::-webkit-scrollbar) { + :root::-webkit-scrollbar-track { + background: transparent; + } +} diff --git a/packages/playground/playground/src/components/icons.rs b/packages/playground/playground/src/components/icons.rs index a5feaf5745..679eddb871 100644 --- a/packages/playground/playground/src/components/icons.rs +++ b/packages/playground/playground/src/components/icons.rs @@ -6,6 +6,7 @@ use dioxus::prelude::*; pub fn Warning() -> Element { rsx! { svg { + height: "16px", xmlns: "http://www.w3.org/2000/svg", fill: "#FFB11F", "viewBox": "0 -960 960 960", diff --git a/packages/playground/playground/src/components/modal.rs b/packages/playground/playground/src/components/modal.rs index a35f7fde63..085f9f244c 100644 --- a/packages/playground/playground/src/components/modal.rs +++ b/packages/playground/playground/src/components/modal.rs @@ -1,3 +1,4 @@ +use crate::dx_components::dialog::{DialogContent, DialogDescription, DialogRoot, DialogTitle}; use dioxus::prelude::*; #[component] @@ -9,37 +10,25 @@ pub fn Modal( on_ok: EventHandler, ) -> Element { let ok_text = ok_text.unwrap_or("Ok".to_string()); + let mut open = use_signal(|| true); rsx! { - // Background - div { - id: "dxp-modal-bg", - - div { - id: "dxp-modal", - - // Modal header with optional icon - div { - id: "dxp-modal-header", - {icon} - h4 { - id: "dxp-modal-title", - "{title}" - } - } - - // Modal description text - p { - id: "dxp-modal-text", - "{text}" - } - - // ok button + DialogRoot { + open: open(), + DialogContent { button { - id: "dxp-modal-ok-btn", - onclick: move |_| on_ok.call(()), - "{ok_text}" + class: "dialog-close", + r#type: "button", + aria_label: "Close", + tabindex: if open() { "0" } else { "-1" }, + onclick: move |_| open.set(false), + "×" + } + DialogTitle { + {icon} + "{title}" } + DialogDescription { "{text}" } } } } diff --git a/packages/playground/playground/src/dx_components/button/component.rs b/packages/playground/playground/src/dx_components/button/component.rs new file mode 100644 index 0000000000..6e6a96780b --- /dev/null +++ b/packages/playground/playground/src/dx_components/button/component.rs @@ -0,0 +1,62 @@ +use dioxus::prelude::*; + +#[derive(Copy, Clone, PartialEq, Default)] +#[non_exhaustive] +pub enum ButtonVariant { + #[default] + Primary, + Secondary, + Destructive, + Outline, + Ghost, +} + +impl ButtonVariant { + pub fn class(&self) -> &'static str { + match self { + ButtonVariant::Primary => "primary", + ButtonVariant::Secondary => "secondary", + ButtonVariant::Destructive => "destructive", + ButtonVariant::Outline => "outline", + ButtonVariant::Ghost => "ghost", + } + } +} + +#[component] +pub fn Button( + #[props(default)] variant: ButtonVariant, + #[props(extends=GlobalAttributes)] + #[props(extends=button)] + attributes: Vec, + onclick: Option>, + onmousedown: Option>, + onmouseup: Option>, + children: Element, +) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + + button { + class: "button", + "data-style": variant.class(), + onclick: move |event| { + if let Some(f) = &onclick { + f.call(event); + } + }, + onmousedown: move |event| { + if let Some(f) = &onmousedown { + f.call(event); + } + }, + onmouseup: move |event| { + if let Some(f) = &onmouseup { + f.call(event); + } + }, + ..attributes, + {children} + } + } +} diff --git a/packages/playground/playground/src/dx_components/button/mod.rs b/packages/playground/playground/src/dx_components/button/mod.rs new file mode 100644 index 0000000000..9a8ae55652 --- /dev/null +++ b/packages/playground/playground/src/dx_components/button/mod.rs @@ -0,0 +1,2 @@ +mod component; +pub use component::*; \ No newline at end of file diff --git a/packages/playground/playground/src/dx_components/button/style.css b/packages/playground/playground/src/dx_components/button/style.css new file mode 100644 index 0000000000..1a02c70ae5 --- /dev/null +++ b/packages/playground/playground/src/dx_components/button/style.css @@ -0,0 +1,54 @@ +.button { + padding: 8px 18px; + border-radius: 0.5rem; + border: none; + cursor: pointer; + font-size: 1rem; + transition: background-color 0.2s ease, color 0.2s ease; +} +.button:focus-visible { + box-shadow: 0 0 0 2px var(--focused-border-color); +} + +.button[data-style="primary"] { + background-color: var(--secondary-color-2); + color: var(--primary-color); +} +.button[data-style="primary"]:hover { + background-color: var(--secondary-color-1); +} + +.button[data-style="secondary"] { + background-color: var(--primary-color-5); + color: var(--secondary-color-1); +} +.button[data-style="secondary"]:hover { + background-color: var(--primary-color-4); +} + +.button[data-style="ghost"] { + background-color: transparent; + color: var(--secondary-color-4); +} +.button[data-style="ghost"]:hover { + background-color: var(--primary-color-5); + color: var(--secondary-color-1); +} + +.button[data-style="outline"] { + border: 1px solid var(--primary-color-6); + background-color: var(--light, var(--primary-color)) + var(--dark, var(--primary-color-3)); + color: var(--secondary-color-4); +} +.button[data-style="outline"]:hover { + background-color: var(--primary-color-4); +} + +.button[data-style="destructive"] { + background-color: var(--primary-error-color); + color: var(--contrast-error-color); +} +.button[data-style="destructive"]:hover { + background-color: var(--secondary-error-color); +} diff --git a/packages/playground/playground/src/dx_components/dialog/component.rs b/packages/playground/playground/src/dx_components/dialog/component.rs new file mode 100644 index 0000000000..63fd6097a4 --- /dev/null +++ b/packages/playground/playground/src/dx_components/dialog/component.rs @@ -0,0 +1,52 @@ +use dioxus::prelude::*; +use dioxus_primitives::dialog::{ + self, DialogContentProps, DialogDescriptionProps, DialogRootProps, DialogTitleProps, +}; + +#[component] +pub fn DialogRoot(props: DialogRootProps) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + dialog::DialogRoot { + class: "dialog-backdrop", + id: props.id, + is_modal: props.is_modal, + open: props.open, + default_open: props.default_open, + on_open_change: props.on_open_change, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn DialogContent(props: DialogContentProps) -> Element { + rsx! { + dialog::DialogContent { class: "dialog", id: props.id, attributes: props.attributes, {props.children} } + } +} + +#[component] +pub fn DialogTitle(props: DialogTitleProps) -> Element { + rsx! { + dialog::DialogTitle { + class: "dialog-title", + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn DialogDescription(props: DialogDescriptionProps) -> Element { + rsx! { + dialog::DialogDescription { + class: "dialog-description", + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} diff --git a/packages/playground/playground/src/dx_components/dialog/mod.rs b/packages/playground/playground/src/dx_components/dialog/mod.rs new file mode 100644 index 0000000000..9a8ae55652 --- /dev/null +++ b/packages/playground/playground/src/dx_components/dialog/mod.rs @@ -0,0 +1,2 @@ +mod component; +pub use component::*; \ No newline at end of file diff --git a/packages/playground/playground/src/dx_components/dialog/style.css b/packages/playground/playground/src/dx_components/dialog/style.css new file mode 100644 index 0000000000..8884e0d532 --- /dev/null +++ b/packages/playground/playground/src/dx_components/dialog/style.css @@ -0,0 +1,104 @@ +/* Dialog Backdrop */ +.dialog-backdrop { + position: fixed; + z-index: 1000; + background: rgb(0 0 0 / 30%); + inset: 0; + opacity: 0; + will-change: transform, opacity; +} + +.dialog-backdrop[data-state="closed"] { + pointer-events: none; + animation: dialog-backdrop-animate-out 150ms ease-in forwards; +} + +@keyframes dialog-backdrop-animate-out { + 0% { + opacity: 1; + transform: scale(1) translateY(0); + } + 100% { + opacity: 0; + transform: scale(0.95) translateY(-2px); + } +} + +.dialog-backdrop[data-state="open"] { + animation: dialog-content-animate-in 150ms ease-out forwards; +} + +@keyframes dialog-content-animate-in { + 0% { + opacity: 0; + transform: scale(0.95) translateY(-2px); + } + 100% { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +/* Dialog Container - improved for theme consistency */ +.dialog { + position: fixed; + z-index: 1001; + top: 50%; + left: 50%; + display: flex; + width: 100%; + max-width: calc(100% - 2rem); + box-sizing: border-box; + flex-direction: column; + padding: 32px 24px 24px; + border: 1px solid var(--primary-color-6); + border-radius: 8px; + margin: 0; + background: var(--primary-color-2); + box-shadow: 0 2px 10px rgb(0 0 0 / 18%); + color: var(--secondary-color-4); + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, + Arial, sans-serif; + gap: 16px; + text-align: center; + transform: translate(-50%, -50%); +} + +.dialog-title { + margin: 0; + color: var(--secondary-color-4); + font-size: 1.25rem; + font-weight: 700; +} + +.dialog-description { + margin: 0; + color: var(--secondary-color-5); + font-size: 1rem; +} + +@media (width >= 40rem) { + .dialog { + max-width: 32rem; + text-align: left; + } +} + +.dialog-close { + position: absolute; + top: 1rem; + right: 1rem; + align-self: flex-start; + padding: 0; + border: none; + margin: 0; + background: none; + color: var(--secondary-color-3); + cursor: pointer; + font-size: 18px; + line-height: 1; +} + +.dialog-close:hover { + color: var(--secondary-color-1); +} diff --git a/packages/playground/playground/src/dx_components/mod.rs b/packages/playground/playground/src/dx_components/mod.rs new file mode 100644 index 0000000000..34c1064068 --- /dev/null +++ b/packages/playground/playground/src/dx_components/mod.rs @@ -0,0 +1,4 @@ +// AUTOGENERTED Components module +pub mod dialog; +pub mod button; +pub mod select; diff --git a/packages/playground/playground/src/dx_components/select/component.rs b/packages/playground/playground/src/dx_components/select/component.rs new file mode 100644 index 0000000000..88e70f02d6 --- /dev/null +++ b/packages/playground/playground/src/dx_components/select/component.rs @@ -0,0 +1,116 @@ +use dioxus::prelude::*; +use dioxus_primitives::select::{ + self, SelectGroupLabelProps, SelectGroupProps, SelectListProps, SelectOptionProps, SelectProps, + SelectTriggerProps, SelectValueProps, +}; + +#[component] +pub fn Select(props: SelectProps) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + select::Select { + class: "select", + value: props.value, + default_value: props.default_value, + on_value_change: props.on_value_change, + disabled: props.disabled, + name: props.name, + placeholder: props.placeholder, + roving_loop: props.roving_loop, + typeahead_timeout: props.typeahead_timeout, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn SelectTrigger(props: SelectTriggerProps) -> Element { + rsx! { + select::SelectTrigger { class: "select-trigger", attributes: props.attributes, + {props.children} + svg { + class: "select-expand-icon", + view_box: "0 0 24 24", + xmlns: "http://www.w3.org/2000/svg", + polyline { points: "6 9 12 15 18 9" } + } + } + } +} + +#[component] +pub fn SelectValue(props: SelectValueProps) -> Element { + rsx! { + select::SelectValue { attributes: props.attributes } + } +} + +#[component] +pub fn SelectList(props: SelectListProps) -> Element { + rsx! { + select::SelectList { + class: "select-list", + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn SelectGroup(props: SelectGroupProps) -> Element { + rsx! { + select::SelectGroup { + class: "select-group", + disabled: props.disabled, + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn SelectGroupLabel(props: SelectGroupLabelProps) -> Element { + rsx! { + select::SelectGroupLabel { + class: "select-group-label", + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn SelectOption(props: SelectOptionProps) -> Element { + rsx! { + select::SelectOption:: { + class: "select-option", + value: props.value, + text_value: props.text_value, + disabled: props.disabled, + id: props.id, + index: props.index, + aria_label: props.aria_label, + aria_roledescription: props.aria_roledescription, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn SelectItemIndicator() -> Element { + rsx! { + select::SelectItemIndicator { + svg { + class: "select-check-icon", + view_box: "0 0 24 24", + xmlns: "http://www.w3.org/2000/svg", + path { d: "M5 13l4 4L19 7" } + } + } + } +} diff --git a/packages/playground/playground/src/dx_components/select/mod.rs b/packages/playground/playground/src/dx_components/select/mod.rs new file mode 100644 index 0000000000..9a8ae55652 --- /dev/null +++ b/packages/playground/playground/src/dx_components/select/mod.rs @@ -0,0 +1,2 @@ +mod component; +pub use component::*; \ No newline at end of file diff --git a/packages/playground/playground/src/dx_components/select/style.css b/packages/playground/playground/src/dx_components/select/style.css new file mode 100644 index 0000000000..31f0eab441 --- /dev/null +++ b/packages/playground/playground/src/dx_components/select/style.css @@ -0,0 +1,153 @@ +.select { + position: relative; +} + +.select-trigger { + position: relative; + display: flex; + box-sizing: border-box; + flex-direction: row; + align-items: center; + justify-content: space-between; + padding: 0.25rem; + padding: 8px 12px; + border: none; + border-radius: 0.5rem; + border-radius: calc(0.5rem); + background: none; + background: var(--light, var(--primary-color)) + var(--dark, var(--primary-color-3)); + box-shadow: inset 0 0 0 1px var(--light, var(--primary-color-6)) + var(--dark, var(--primary-color-7)); + color: var(--secondary-color-4); + cursor: pointer; + gap: 0.25rem; + transition: background-color 100ms ease-out; +} + +.select-trigger span[data-placeholder="true"] { + color: var(--secondary-color-5); +} + +.select[data-state="open"] .select-trigger { + pointer-events: none; +} + +.select-expand-icon { + width: 20px; + height: 20px; + fill: none; + stroke: var(--primary-color-7); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; +} + +.select-check-icon { + width: 1rem; + height: 1rem; + fill: none; + stroke: var(--secondary-color-5); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; +} + +.select[data-disabled="true"] .select-trigger { + color: var(--secondary-color-5); + cursor: not-allowed; +} + +.select-trigger:hover:not([data-disabled="true"]), +.select-trigger:focus-visible { + background: var(--light, var(--primary-color-4)) + var(--dark, var(--primary-color-5)); + color: var(--secondary-color-1); + outline: none; +} + +.select-list { + position: absolute; + z-index: 1000; + top: 100%; + left: 0; + min-width: 100%; + box-sizing: border-box; + padding: 0.25rem; + border-radius: 0.5rem; + margin-top: 0.25rem; + background: var(--light, var(--primary-color)) + var(--dark, var(--primary-color-5)); + box-shadow: inset 0 0 0 1px var(--light, var(--primary-color-6)) + var(--dark, var(--primary-color-7)); + transform-origin: top; + opacity: 0; + pointer-events: none; + will-change: transform, opacity; +} + +.select-list[data-state="closed"] { + pointer-events: none; + animation: select-list-animate-out 150ms ease-in forwards; +} + +@keyframes select-list-animate-out { + 0% { + opacity: 1; + transform: scale(1) translateY(0); + } + 100% { + opacity: 0; + transform: scale(0.95) translateY(-2px); + } +} + +.select-list[data-state="open"] { + pointer-events: auto; + animation: select-list-animate-in 150ms ease-out forwards; +} + +@keyframes select-list-animate-in { + 0% { + opacity: 0; + transform: scale(0.95) translateY(-2px); + } + 100% { + opacity: 1; + transform: scale(1) translateY(0); + } +} + +.select-option { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px 12px; + border-radius: calc(0.5rem - 0.25rem); + cursor: pointer; + font-size: 14px; +} + +.select-option[data-disabled="true"] { + color: var(--secondary-color-5); + cursor: not-allowed; +} + +.select-option:hover:not([data-disabled="true"]), +.select-option:focus-visible { + background: var(--light, var(--primary-color-4)) + var(--dark, var(--primary-color-7)); + color: var(--secondary-color-1); + outline: none; +} + +.select-group-label { + padding: 4px 12px; + color: var(--secondary-color-5); + font-size: 0.75rem; +} + +[data-disabled="true"] { + cursor: not-allowed; + opacity: 0.5; +} diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 938dd5376a..36105a907d 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -13,6 +13,7 @@ use dioxus_sdk::window::theme::{use_system_theme, Theme}; mod build; mod components; +mod dx_components; mod editor; mod hotreload; mod share_code; @@ -20,6 +21,7 @@ mod ws; const DXP_CSS: Asset = asset!("/assets/dxp.css"); const MONACO_FOLDER: Asset = asset!("/assets/monaco-editor-0.52.2"); +const DX_COMPONENTS_CSS: Asset = asset!("/assets/dx-components-theme.css"); /// The URLS that the playground should use for locating resources and services. #[derive(Debug, Clone, PartialEq)] @@ -141,6 +143,7 @@ pub fn Playground( div { class, id: "dxp-playground-root", // Head elements Link { rel: "stylesheet", href: DXP_CSS } + Link { rel: "stylesheet", href: DX_COMPONENTS_CSS } // Monaco script script { diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 114c057c06..d77165eb46 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -1516,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" +name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" version = "0.1.0" dependencies = [ "dioxus", diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index acd6e4c58d..7a5c3ec118 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -2,13 +2,17 @@ [workspace] [package] -name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" version = "0.1.0" edition = "2024" [dependencies] -dioxus = { path = "../../../../../dioxus/packages/dioxus", features = ["web", "router", "launch", "logger", "lib"], default-features = false } +dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } +time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } +tracing = "0.1.41" wasm-bindgen = "=0.2.100" +web-sys = { version = "0.3", features = ["Location"] } [profile.dev.package."*"] opt-level = 3 @@ -24,3 +28,15 @@ strip = true opt-level = 3 debug = true strip = true + +[patch.crates-io] +dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond = { git = "https://github.com/dioxuslabs/dioxus" } +subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } +generational-box = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml index c190b50393..feb660d85c 100644 --- a/packages/playground/server/template/Dioxus.toml +++ b/packages/playground/server/template/Dioxus.toml @@ -1,12 +1,12 @@ [application] -name = "57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "5f1689ca-25e2-3fea-96d4-75ad3e26efa9" default_platform = "web" out_dir = "dist" -asset_dir = "public" +asset_dir = "assets" hot_reload = false [web.app] -base_path = "built/57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +base_path = "built/5f1689ca-25e2-3fea-96d4-75ad3e26efa9" title = "Dioxus Playground" [web.watcher] @@ -20,4 +20,3 @@ script = [] [application.plugins] available = true required = [] - diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 2a4f50e2fb..5cfde7b728 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -1,4 +1,5 @@ -//! The simplest Dioxus app +//! A basic counter example demonstrating signals, +//! event handlers, and basic rendering. use dioxus::prelude::*; @@ -8,7 +9,13 @@ fn main() { #[component] fn App() -> Element { + let mut count = use_signal(|| 0); + rsx! { - div { "Build" } + p { "Count: {count*2}" } + div { style: "display: flex;", + button { onclick: move |_| count -= 1, "-" } + button { onclick: move |_| count += 1, "+" } + } } } From 9f33b1f5818da5adba5f5feb4772d6bec0eb0d55 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 7 Oct 2025 12:50:53 -0500 Subject: [PATCH 26/58] examples dropdown --- Cargo.lock | 1188 +++++++++-------- Cargo.toml | 10 +- .../src/doc_examples/use_effect.rs | 2 +- .../src/doc_examples/use_resource.rs | 2 +- packages/docsite/src/components/awesome.rs | 2 +- .../docsite/src/components/component_demo.rs | 4 +- packages/playground/playground/Cargo.toml | 2 +- .../playground/src/components/header.rs | 48 +- packages/playground/playground/src/lib.rs | 19 +- packages/playground/runner/src/main.rs | 2 +- .../playground/server/template/Cargo.lock | 4 +- .../playground/server/template/Cargo.toml | 4 +- .../playground/server/template/Dioxus.toml | 4 +- .../server/template/snippets/Cargo.toml | 2 +- .../playground/server/template/src/main.rs | 11 +- 15 files changed, 669 insertions(+), 635 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bdcefa22d8..68a2543048 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -258,6 +258,22 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "async-tungstenite" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee88b4c88ac8c9ea446ad43498955750a4bbe64c4392f21ccfe5d952865e318f" +dependencies = [ + "atomic-waker", + "futures-core", + "futures-io", + "futures-task", + "futures-util", + "log", + "pin-project-lite", + "tungstenite 0.27.0", +] + [[package]] name = "atk" version = "0.18.2" @@ -451,6 +467,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-extra" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9963ff19f40c6102c76756ef0a46004c0d58957d87259fc9208ff8441c12ab96" +dependencies = [ + "axum 0.8.6", + "axum-core 0.5.5", + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "serde_core", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "axum-macros" version = "0.5.0" @@ -474,7 +513,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -548,9 +587,9 @@ dependencies = [ [[package]] name = "block2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ "objc2", ] @@ -590,9 +629,9 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" @@ -674,9 +713,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.39" +version = "1.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" dependencies = [ "find-msvc-tools", "jobserver", @@ -723,6 +762,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "charset" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" +dependencies = [ + "base64 0.22.1", + "encoding_rs", +] + [[package]] name = "chrono" version = "0.4.42" @@ -734,7 +783,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -908,7 +957,7 @@ dependencies = [ "libc", "once_cell", "unicode-width", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -953,37 +1002,16 @@ dependencies = [ [[package]] name = "const-serialize" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c02a1f46ffe1c6f05edf568a7d8e2ab477c75a6ec5f33d2b83ce54fc3f096ca" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "const-serialize-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "const-serialize-macro", "serde", ] -[[package]] -name = "const-serialize" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" -dependencies = [ - "const-serialize-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "serde", -] - -[[package]] -name = "const-serialize-macro" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1da74b91de7c3426afaed28ed514bc4cd39821eeecf9f32dc424023310a63ae4" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - [[package]] name = "const-serialize-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "proc-macro2", "quote", @@ -992,15 +1020,15 @@ dependencies = [ [[package]] name = "const-str" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451d0640545a0553814b4c646eb549343561618838e9b42495f466131fe3ad49" +checksum = "f4d34b8f066904ed7cfa4a6f9ee96c3214aa998cb44b69ca20bd2054f47402ed" [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -1016,6 +1044,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "content_disposition" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc14a88e1463ddd193906285abe5c360c7e8564e05ccc5d501755f7fbc9ca9c" +dependencies = [ + "charset", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1046,10 +1083,29 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ + "percent-encoding", "time", "version_check", ] +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1318,6 +1374,27 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", + "unicode-xid", +] + [[package]] name = "diff" version = "0.1.13" @@ -1337,20 +1414,21 @@ dependencies = [ [[package]] name = "dioxus" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "dioxus-asset-resolver 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-asset-resolver", "dioxus-cli-config", - "dioxus-config-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-config-macro", "dioxus-config-macros", "dioxus-core", "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools", "dioxus-document", "dioxus-fullstack", + "dioxus-fullstack-macro", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", "dioxus-liveview 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-logger", "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", @@ -1358,8 +1436,7 @@ dependencies = [ "dioxus-signals", "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-stores", - "dioxus-web 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus_server_macro", + "dioxus-web", "manganis", "serde", "subsecond", @@ -1369,34 +1446,20 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b6782436b323a84b4d9f90cf2365b35a1cdb918191221f71865dcc2e70016b6" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-cli-config", "http", "infer", "jni", - "manganis-core 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "manganis-core", "ndk", "ndk-context", "ndk-sys", "percent-encoding", "thiserror 2.0.17", "tokio", -] - -[[package]] -name = "dioxus-asset-resolver" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" -dependencies = [ - "jni", - "js-sys", - "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "ndk", - "ndk-context", - "ndk-sys", - "thiserror 2.0.17", "wasm-bindgen-futures", "web-sys", ] @@ -1407,7 +1470,7 @@ version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e26d7984c2730639f0d83dcf727b66ec01acb9954fa8b62b9ee11138b033da88" dependencies = [ - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx", "prettyplease", "proc-macro2", "quote", @@ -1417,27 +1480,31 @@ dependencies = [ ] [[package]] -name = "dioxus-cli-config" +name = "dioxus-autofmt" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "wasm-bindgen", + "dioxus-rsx", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "serde", + "syn 2.0.106", ] [[package]] -name = "dioxus-config-macro" +name = "dioxus-cli-config" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0711887c38dcebd391bfa5a0759c79ffcc5b0c21ee120cf3d99c42346eb626d" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "proc-macro2", - "quote", + "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "proc-macro2", "quote", @@ -1446,15 +1513,16 @@ dependencies = [ [[package]] name = "dioxus-config-macros" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" [[package]] name = "dioxus-core" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ + "anyhow", "const_format", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", "futures-channel", "futures-util", "generational-box", @@ -1476,7 +1544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9280f81c8d58863b3077f1b7ca097e2f2b28d30a5aa02a656fbf72b0aee1bd9f" dependencies = [ "convert_case 0.8.0", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx", "proc-macro2", "quote", "syn 2.0.106", @@ -1485,10 +1553,10 @@ dependencies = [ [[package]] name = "dioxus-core-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "convert_case 0.8.0", - "dioxus-rsx 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-rsx", "proc-macro2", "quote", "syn 2.0.106", @@ -1497,33 +1565,27 @@ dependencies = [ [[package]] name = "dioxus-core-types" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ef2a94b4ceb8f7a39f56a539d07e82b0358a49a0b95028ad48635975df29d7" - -[[package]] -name = "dioxus-core-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" [[package]] name = "dioxus-desktop" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8190b532291840504195a5aeb9125f53df2001006acdcd876929d64ecdac1fc8" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "async-trait", "base64 0.22.1", + "bytes", "cocoa", "core-foundation 0.10.1", - "dioxus-asset-resolver 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-asset-resolver", "dioxus-cli-config", "dioxus-core", - "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-interpreter-js", "dioxus-signals", "dunce", "futures-channel", @@ -1532,7 +1594,7 @@ dependencies = [ "global-hotkey", "infer", "jni", - "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy-js-bundle 0.7.0-rc.0", "libc", "muda", "ndk", @@ -1562,31 +1624,14 @@ dependencies = [ [[package]] name = "dioxus-devtools" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60af4e129968ab1713471ed0b29c3eefa4e8e09252429487d7a581e93c7ecfe5" -dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-signals", - "serde", - "serde_json", - "subsecond", - "thiserror 2.0.17", - "tracing", - "tungstenite 0.27.0", - "warnings", -] - -[[package]] -name = "dioxus-devtools" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-cli-config", "dioxus-core", - "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools-types", "dioxus-signals", + "futures-channel", + "futures-util", "serde", "serde_json", "subsecond", @@ -1599,18 +1644,7 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64274704b6a8d018112473cdce0b3db1dcccfa79bde445223592fe4e396ff5ef" -dependencies = [ - "dioxus-core", - "serde", - "subsecond-types", -] - -[[package]] -name = "dioxus-devtools-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "serde", @@ -1704,7 +1738,7 @@ dependencies = [ "dioxus-desktop", "dioxus-liveview 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-ssr 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-web 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-web", "form_urlencoded", "futures", "futures-util", @@ -1734,16 +1768,16 @@ dependencies = [ [[package]] name = "dioxus-document" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", + "dioxus-html", "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "lazy-js-bundle 0.7.0-rc.0", "serde", "serde_json", "tracing", @@ -1752,10 +1786,10 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "cargo_metadata", - "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "manganis-core", "serde", "serde_json", "subsecond-types", @@ -1764,69 +1798,103 @@ dependencies = [ [[package]] name = "dioxus-fullstack" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ + "anyhow", + "async-stream", + "async-tungstenite", + "axum 0.8.6", + "axum-core 0.5.5", + "axum-extra", "base64 0.22.1", "bytes", "ciborium", + "const-str", + "const_format", + "content_disposition", + "derive_more 2.0.1", + "dioxus-asset-resolver", + "dioxus-cli-config", "dioxus-core", - "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-document", - "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-server", - "dioxus-web 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus_server_macro", + "dioxus-fullstack-core", + "dioxus-fullstack-macro", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-signals", + "form_urlencoded", + "futures", "futures-channel", "futures-util", - "generational-box", + "gloo-net", + "headers", "http", + "http-body", + "http-body-util", + "inventory", + "js-sys", + "mime", + "pin-project 1.1.10", + "reqwest", + "rustversion", + "send_wrapper", "serde", - "server_fn", + "serde_json", + "serde_qs", + "serde_urlencoded", + "thiserror 2.0.17", + "tokio", + "tokio-stream", + "tokio-tungstenite 0.27.0", + "tokio-util", + "tower 0.5.2", + "tower-http 0.6.6", + "tower-layer", "tracing", + "tungstenite 0.27.0", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", "web-sys", + "xxhash-rust", ] [[package]] -name = "dioxus-fullstack-hooks" +name = "dioxus-fullstack-core" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ + "anyhow", + "axum-core 0.5.5", + "base64 0.22.1", + "ciborium", "dioxus-core", "dioxus-document", - "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", "futures-channel", + "futures-util", + "generational-box", + "http", + "inventory", "serde", -] - -[[package]] -name = "dioxus-fullstack-protocol" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f266ad9e20be14b8899f2133dd942131f03e6749650e65e2aaec2c7f8a4bc1" -dependencies = [ - "base64 0.22.1", - "ciborium", - "dioxus-core", - "serde", + "serde_json", + "thiserror 2.0.17", "tracing", ] [[package]] -name = "dioxus-fullstack-protocol" +name = "dioxus-fullstack-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "base64 0.22.1", - "ciborium", - "dioxus-core", - "serde", - "tracing", + "const_format", + "convert_case 0.8.0", + "proc-macro2", + "quote", + "syn 2.0.106", + "xxhash-rust", ] [[package]] @@ -1842,7 +1910,7 @@ dependencies = [ [[package]] name = "dioxus-history" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "tracing", @@ -1868,7 +1936,7 @@ dependencies = [ [[package]] name = "dioxus-hooks" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1884,46 +1952,23 @@ dependencies = [ [[package]] name = "dioxus-html" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "073e5b69a7b66e9cbb49530df8c4cf86bf2aff3322ba86a3d722f9d58cd9c54b" -dependencies = [ - "async-trait", - "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html-internal-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "enumset", - "euclid", - "futures-channel", - "generational-box", - "keyboard-types", - "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustversion", - "serde", - "serde_json", - "serde_repr", - "tracing", -] - -[[package]] -name = "dioxus-html" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "async-trait", + "bytes", "dioxus-core", "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html-internal-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html-internal-macro", + "dioxus-rsx", "enumset", "euclid", "futures-channel", + "futures-util", "generational-box", "keyboard-types", - "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "lazy-js-bundle 0.7.0-rc.0", "rustversion", "serde", "serde_json", @@ -1934,19 +1979,7 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162beea862dc888897a0b527db08724ede0f09e59fe081ab39caa0b085f40e10" -dependencies = [ - "convert_case 0.8.0", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "dioxus-html-internal-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -1957,14 +1990,13 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd2ef3fe9bddfcac6d2ccf123d4834b5c3d97e6f2be8fcbfc4943226d9d7d4fe" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types", + "dioxus-html", "js-sys", - "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy-js-bundle 0.7.0-rc.0", "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", @@ -1974,38 +2006,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "dioxus-interpreter-js" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" -dependencies = [ - "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "js-sys", - "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "rustc-hash 2.1.1", - "sledgehammer_bindgen", - "sledgehammer_utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "dioxus-isrg" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" -dependencies = [ - "chrono", - "http", - "lru", - "rustc-hash 2.1.1", - "thiserror 2.0.17", - "tracing", - "walkdir", -] - [[package]] name = "dioxus-liveview" version = "0.7.0-rc.0" @@ -2015,11 +2015,11 @@ dependencies = [ "axum 0.8.6", "dioxus-cli-config", "dioxus-core", - "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-devtools", "dioxus-document", "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html", + "dioxus-interpreter-js", "futures-channel", "futures-util", "generational-box", @@ -2037,16 +2037,16 @@ dependencies = [ [[package]] name = "dioxus-liveview" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "axum 0.8.6", "dioxus-cli-config", "dioxus-core", - "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools", "dioxus-document", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-interpreter-js", "futures-channel", "futures-util", "generational-box", @@ -2064,7 +2064,7 @@ dependencies = [ [[package]] name = "dioxus-logger" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-cli-config", "tracing", @@ -2078,14 +2078,14 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "dioxus", - "dioxus-autofmt", + "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types", + "dioxus-devtools", "dioxus-document", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html", "dioxus-primitives", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", "dioxus-sdk", @@ -2108,10 +2108,10 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" +source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" dependencies = [ "dioxus", - "dioxus-time", + "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=0.7)", "lazy-js-bundle 0.6.2", "time", "tracing", @@ -2128,7 +2128,7 @@ dependencies = [ "dioxus-core-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html", "dioxus-router-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-signals", "percent-encoding", @@ -2140,15 +2140,15 @@ dependencies = [ [[package]] name = "dioxus-router" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-cli-config", "dioxus-core", "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-fullstack-hooks", + "dioxus-fullstack-core", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", "dioxus-router-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", "percent-encoding", @@ -2175,7 +2175,7 @@ dependencies = [ [[package]] name = "dioxus-router-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "base16", "digest", @@ -2189,19 +2189,7 @@ dependencies = [ [[package]] name = "dioxus-rsx" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee08e1302f384a54d97b762eddb57cf3b7335b08b176e136c1d9631b5c71ff18" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "dioxus-rsx" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -2216,8 +2204,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c796e02557a4de1f4b4850e554b802b7bcce607103e0b1d5b4c530268791005e" dependencies = [ "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types", + "dioxus-rsx", "internment", "proc-macro2", "proc-macro2-diagnostics", @@ -2229,13 +2217,12 @@ dependencies = [ [[package]] name = "dioxus-rsx-rosetta" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1891c187301f3fed87ab2b18a58e473404bdb35c9fed6beadefcdd7801d96787" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "convert_case 0.8.0", - "dioxus-autofmt", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-rsx", "html_parser", "htmlentity", "proc-macro2", @@ -2246,9 +2233,9 @@ dependencies = [ [[package]] name = "dioxus-sdk" version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" dependencies = [ - "dioxus-time", + "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=git)", "dioxus-util", "dioxus-window", ] @@ -2299,56 +2286,64 @@ dependencies = [ [[package]] name = "dioxus-server" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ + "anyhow", "async-trait", "axum 0.8.6", "base64 0.22.1", "bytes", + "chrono", "ciborium", "dashmap", "dioxus-cli-config", "dioxus-core", "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools", "dioxus-document", - "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-fullstack-core", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-isrg", + "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-interpreter-js", + "dioxus-logger", "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-signals", "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", "enumset", + "futures", "futures-channel", "futures-util", "generational-box", "http", + "http-body-util", "hyper", "hyper-util", "inventory", + "lru", "parking_lot", "pin-project 1.1.10", + "rustc-hash 2.1.1", "serde", - "server_fn", + "serde_json", + "serde_qs", "subsecond", "thiserror 2.0.17", "tokio", + "tokio-tungstenite 0.27.0", "tokio-util", "tower 0.5.2", "tower-http 0.6.6", - "tower-layer", "tracing", "tracing-futures", - "web-sys", + "url", + "walkdir", ] [[package]] name = "dioxus-signals" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "futures-channel", @@ -2368,25 +2363,25 @@ checksum = "21c377da1f2ea708be1112dd61189d6dcd19c8db25208b750c3849f760fa854d" dependencies = [ "askama_escape 0.13.0", "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-types", "rustc-hash 2.1.1", ] [[package]] name = "dioxus-ssr" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "askama_escape 0.13.0", "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", "rustc-hash 2.1.1", ] [[package]] name = "dioxus-stores" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2396,7 +2391,7 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2416,87 +2411,65 @@ dependencies = [ ] [[package]] -name = "dioxus-util" +name = "dioxus-time" version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" dependencies = [ "dioxus", - "serde", -] - -[[package]] -name = "dioxus-web" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34eb4f341b0203f7b1fe1804d4561a19a399bf7fa4821a5b87cff5fd89d834bd" -dependencies = [ - "async-trait", - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-document", - "dioxus-fullstack-protocol 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-interpreter-js 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-signals", - "futures-channel", - "futures-util", - "generational-box", + "futures", "gloo-timers", - "js-sys", - "lazy-js-bundle 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hash 2.1.1", + "tokio", +] + +[[package]] +name = "dioxus-util" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" +dependencies = [ + "dioxus", "serde", - "serde-wasm-bindgen", - "serde_json", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", ] [[package]] name = "dioxus-web" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "async-trait", "dioxus-cli-config", "dioxus-core", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-devtools 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", + "dioxus-devtools", "dioxus-document", - "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-fullstack-core", "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-html 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-interpreter-js 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-html", + "dioxus-interpreter-js", "dioxus-signals", "futures-channel", "futures-util", "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "lazy-js-bundle 0.7.0-rc.0", "rustc-hash 2.1.1", + "send_wrapper", "serde", "serde-wasm-bindgen", "serde_json", "tracing", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", ] [[package]] name = "dioxus-window" version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" dependencies = [ "dioxus", - "dioxus-config-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-config-macro", "dioxus-desktop", "wasm-bindgen", "web-sys", @@ -2521,7 +2494,7 @@ dependencies = [ "dioxus-docs-examples", "dioxus-playground", "dioxus-search", - "dioxus-web 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-web", "futures", "futures-util", "getrandom 0.2.16", @@ -2545,17 +2518,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "dioxus_server_macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" -dependencies = [ - "proc-macro2", - "quote", - "server_fn_macro", - "syn 2.0.106", -] - [[package]] name = "dirs" version = "6.0.0" @@ -2574,7 +2536,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -2644,6 +2606,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + [[package]] name = "downcast-rs" version = "1.2.1" @@ -2797,7 +2768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -2916,15 +2887,15 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "miniz_oxide", @@ -3233,7 +3204,7 @@ dependencies = [ [[package]] name = "generational-box" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "parking_lot", "tracing", @@ -3657,6 +3628,30 @@ dependencies = [ "num-traits", ] +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64 0.22.1", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http", +] + [[package]] name = "heapless" version = "0.7.17" @@ -3836,6 +3831,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] @@ -3905,7 +3901,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.62.1", + "windows-core 0.62.2", ] [[package]] @@ -4332,13 +4328,7 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22c4abc3d491546025db72681ed8b1ff0e6e77d67f196460179b027d591b6ff" - -[[package]] -name = "lazy-js-bundle" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" [[package]] name = "lazy_static" @@ -4409,7 +4399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -4469,13 +4459,18 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] @@ -4509,6 +4504,12 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac" version = "0.1.1" @@ -4560,42 +4561,32 @@ dependencies = [ [[package]] name = "manganis" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "const-serialize 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "const-serialize", + "manganis-core", "manganis-macro", ] [[package]] name = "manganis-core" version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71ef461824c58f3d260c1f548f7a8aee2e0b6b805a503d15f8535a3a6272d7" -dependencies = [ - "const-serialize 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde", -] - -[[package]] -name = "manganis-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ - "const-serialize 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "const-serialize", "dioxus-cli-config", - "dioxus-core-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-types", "serde", ] [[package]] name = "manganis-macro" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "dunce", "macro-string", - "manganis-core 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "manganis-core", "proc-macro2", "quote", "syn 2.0.106", @@ -4693,8 +4684,8 @@ version = "0.0.0" dependencies = [ "anyhow", "convert_case 0.6.0", - "dioxus-autofmt", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx", "macro_state", "mdbook-shared", "once_cell", @@ -4716,7 +4707,7 @@ name = "mdbook-gen-example" version = "0.0.0" dependencies = [ "dioxus", - "dioxus-autofmt", + "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook-gen", "mdbook-shared", "prettyplease", @@ -4731,7 +4722,7 @@ version = "0.1.0" dependencies = [ "anyhow", "convert_case 0.6.0", - "dioxus-rsx 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-rsx", "macro_state", "mdbook-gen", "mdbook-shared", @@ -4842,7 +4833,7 @@ name = "model" version = "0.1.0" dependencies = [ "axum 0.8.6", - "dioxus-devtools 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-devtools", "dioxus-document", "dioxus-dx-wire-format", "dioxus-logger", @@ -4857,9 +4848,9 @@ dependencies = [ [[package]] name = "moxcms" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +checksum = "1cc7d85f3d741164e8972ad355e26ac6e51b20fcae5f911c7da8f2d8bbbb3f33" dependencies = [ "num-traits", "pxfm", @@ -5124,9 +5115,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ "objc2-encode", "objc2-exception-helper", @@ -5134,9 +5125,9 @@ dependencies = [ [[package]] name = "objc2-app-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.9.4", "block2", @@ -5147,9 +5138,9 @@ dependencies = [ [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ "bitflags 2.9.4", "dispatch2", @@ -5158,9 +5149,9 @@ dependencies = [ [[package]] name = "objc2-core-graphics" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ "bitflags 2.9.4", "objc2-core-foundation", @@ -5183,9 +5174,9 @@ dependencies = [ [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ "bitflags 2.9.4", "block2", @@ -5195,9 +5186,9 @@ dependencies = [ [[package]] name = "objc2-ui-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ "bitflags 2.9.4", "objc2", @@ -5207,9 +5198,9 @@ dependencies = [ [[package]] name = "objc2-web-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ "bitflags 2.9.4", "block2", @@ -5364,9 +5355,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -5374,15 +5365,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -5399,20 +5390,19 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e0a3a33733faeaf8651dfee72dd0f388f0c8e5ad496a3478fa5a922f49cfa8" +checksum = "989e7521a040efde50c3ab6bbadafbe15ab6dc042686926be59ac35d74607df4" dependencies = [ "memchr", - "thiserror 2.0.17", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc58706f770acb1dbd0973e6530a3cff4746fb721207feb3a8a6064cd0b6c663" +checksum = "187da9a3030dbafabbbfb20cb323b976dc7b7ce91fcd84f2f74d6e31d378e2de" dependencies = [ "pest", "pest_generator", @@ -5420,9 +5410,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d4f36811dfe07f7b8573462465d5cb8965fffc2e71ae377a33aecf14c2c9a2f" +checksum = "49b401d98f5757ebe97a26085998d6c0eecec4995cad6ab7fc30ffdf4b052843" dependencies = [ "pest", "pest_meta", @@ -5433,9 +5423,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42919b05089acbd0a5dcd5405fb304d17d1053847b81163d09c4ad18ce8e8420" +checksum = "72f27a2cfee9f9039c4d86faa5af122a0ac3851441a34865b8a043b46be0065a" dependencies = [ "pest", "sha2", @@ -5893,6 +5883,22 @@ dependencies = [ "prost", ] +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + [[package]] name = "pulldown-cmark" version = "0.9.6" @@ -5990,6 +5996,61 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2 0.6.0", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.6.0", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.41" @@ -6208,9 +6269,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags 2.9.4", ] @@ -6263,6 +6324,8 @@ checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" dependencies = [ "base64 0.22.1", "bytes", + "cookie", + "cookie_store", "encoding_rs", "futures-core", "futures-util", @@ -6277,10 +6340,11 @@ dependencies = [ "js-sys", "log", "mime", - "mime_guess", "native-tls", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pki-types", "serde", "serde_json", @@ -6288,6 +6352,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-native-tls", + "tokio-rustls", "tokio-util", "tower 0.5.2", "tower-http 0.6.6", @@ -6297,6 +6362,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots", ] [[package]] @@ -6436,7 +6502,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -6446,6 +6512,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -6458,6 +6525,7 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ + "web-time", "zeroize", ] @@ -6499,7 +6567,7 @@ version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -6560,7 +6628,7 @@ checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" dependencies = [ "bitflags 1.3.2", "cssparser 0.27.2", - "derive_more", + "derive_more 0.99.20", "fxhash", "log", "matches", @@ -6580,7 +6648,7 @@ checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" dependencies = [ "bitflags 1.3.2", "cssparser 0.29.6", - "derive_more", + "derive_more 0.99.20", "fxhash", "log", "phf 0.8.0", @@ -6598,7 +6666,7 @@ checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" dependencies = [ "bitflags 2.9.4", "cssparser 0.34.0", - "derive_more", + "derive_more 0.99.20", "fxhash", "log", "new_debug_unreachable", @@ -6745,7 +6813,7 @@ dependencies = [ "console-subscriber", "dashmap", "dioxus", - "dioxus-devtools-types 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-devtools-types", "dioxus-dx-wire-format", "dioxus-logger", "example-projects", @@ -6769,73 +6837,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "server_fn" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" -dependencies = [ - "axum 0.8.6", - "base64 0.22.1", - "bytes", - "const-str", - "const_format", - "dashmap", - "futures", - "gloo-net", - "http", - "http-body-util", - "hyper", - "inventory", - "js-sys", - "pin-project-lite", - "reqwest", - "rustc_version", - "rustversion", - "send_wrapper", - "serde", - "serde_json", - "serde_qs", - "server_fn_macro_default", - "thiserror 2.0.17", - "throw_error", - "tokio", - "tokio-tungstenite 0.27.0", - "tower 0.5.2", - "tower-layer", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "xxhash-rust", -] - -[[package]] -name = "server_fn_macro" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d530c872590473016016679c94e3bddf47372941fc924f687ffd11a1778a71" -dependencies = [ - "const_format", - "convert_case 0.8.0", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.106", - "xxhash-rust", -] - -[[package]] -name = "server_fn_macro_default" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca7abc92ed696648275ed9ff171131a83d571af11748593dc2e6eb6a4e22a5b9" -dependencies = [ - "server_fn_macro", - "syn 2.0.106", -] - [[package]] name = "servo_arc" version = "0.1.1" @@ -7150,7 +7151,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "js-sys", "libc", @@ -7168,7 +7169,7 @@ dependencies = [ [[package]] name = "subsecond-types" version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#ad40f816073f91da67c0287a5512a5111e5a1617" +source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" dependencies = [ "serde", ] @@ -7354,7 +7355,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -7423,15 +7424,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "throw_error" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e42a6afdde94f3e656fae18f837cb9bbe500a5ac5de325b09f3ec05b9c28e3" -dependencies = [ - "pin-project-lite", -] - [[package]] name = "tiff" version = "0.10.3" @@ -7487,6 +7479,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.47.1" @@ -7548,6 +7555,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", ] [[package]] @@ -7582,6 +7590,7 @@ checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "futures-util", "pin-project-lite", @@ -8087,9 +8096,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -8508,6 +8517,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-roots" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.0" @@ -8572,7 +8590,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -8618,15 +8636,15 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.62.1" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link 0.2.0", - "windows-result 0.4.0", - "windows-strings 0.5.0", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -8642,9 +8660,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.1" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -8653,9 +8671,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.2" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -8670,9 +8688,9 @@ checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" @@ -8706,11 +8724,11 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -8724,11 +8742,11 @@ dependencies = [ [[package]] name = "windows-strings" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -8764,16 +8782,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.4", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -8809,19 +8827,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.4" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.2.0", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -8835,11 +8853,11 @@ dependencies = [ [[package]] name = "windows-version" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "700dad7c058606087f6fdc1f88da5841e06da40334413c6cd4367b25ef26d24e" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" dependencies = [ - "windows-link 0.2.0", + "windows-link 0.2.1", ] [[package]] @@ -8856,9 +8874,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -8874,9 +8892,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -8892,9 +8910,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -8904,9 +8922,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -8922,9 +8940,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -8940,9 +8958,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -8958,9 +8976,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -8976,9 +8994,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" @@ -9362,6 +9380,16 @@ name = "dioxus-sync" version = "0.7.0-rc.0" source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" +[[patch.unused]] +name = "dioxus-util" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" + +[[patch.unused]] +name = "dioxus-window" +version = "0.7.0-rc.0" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" + [[patch.unused]] name = "dioxus_storage" version = "0.7.0-rc.0" diff --git a/Cargo.toml b/Cargo.toml index 1426991731..a7e2ac8653 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,7 +124,7 @@ codegen-units = 1 [patch.crates-io] dioxus-geolocation = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-notification = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "git" } dioxus_storage = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-sync = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } dioxus-time = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } @@ -133,6 +133,7 @@ dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } dioxus = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-core-types = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } @@ -140,3 +141,10 @@ subsecond = { git = "https://github.com/dioxuslabs/dioxus" } subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } generational-box = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-devtools = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-rsx = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-desktop = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-web = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-html = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-interpreter-js = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-rsx-rosetta = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/docs-router/src/doc_examples/use_effect.rs b/packages/docs-router/src/doc_examples/use_effect.rs index 9fd6f19802..8cfb640d98 100644 --- a/packages/docs-router/src/doc_examples/use_effect.rs +++ b/packages/docs-router/src/doc_examples/use_effect.rs @@ -2,7 +2,7 @@ use dioxus::prelude::*; #[component] -fn Profile(id: ReadOnlySignal) -> Element { +fn Profile(id: ReadSignal) -> Element { // Only change the page title when the id changes use_effect(move || { // We read the id signal here, so it will automatically be added as a dependency for the effect diff --git a/packages/docs-router/src/doc_examples/use_resource.rs b/packages/docs-router/src/doc_examples/use_resource.rs index dcb4a16933..43b1600769 100644 --- a/packages/docs-router/src/doc_examples/use_resource.rs +++ b/packages/docs-router/src/doc_examples/use_resource.rs @@ -42,7 +42,7 @@ pub fn App() -> Element { } #[component] -fn RandomDog(breed: ReadOnlySignal) -> Element { +fn RandomDog(breed: ReadSignal) -> Element { // ANCHOR: dependency let future = use_resource(move || async move { reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) diff --git a/packages/docsite/src/components/awesome.rs b/packages/docsite/src/components/awesome.rs index 15a95cf47b..1b802df4a5 100644 --- a/packages/docsite/src/components/awesome.rs +++ b/packages/docsite/src/components/awesome.rs @@ -193,7 +193,7 @@ pub(crate) fn Awesome() -> Element { } #[component] -fn AwesomeItem(item: ReadOnlySignal) -> Element { +fn AwesomeItem(item: ReadSignal) -> Element { let stars = use_resource(move || async move { let item = item.read(); let is_github = item.github.is_some(); diff --git a/packages/docsite/src/components/component_demo.rs b/packages/docsite/src/components/component_demo.rs index d48da0aab5..37c4d229c7 100644 --- a/packages/docsite/src/components/component_demo.rs +++ b/packages/docsite/src/components/component_demo.rs @@ -3,8 +3,8 @@ use dioxus::prelude::*; #[component] pub(crate) fn Components() -> Element { - let segments: ReadOnlySignal> = Default::default(); - let query: ReadOnlySignal = Default::default(); + let segments: ReadSignal> = Default::default(); + let query: ReadSignal = Default::default(); fn format_segments(segments: &[String], query: &str) -> String { let segments = segments.join("/"); diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index c65e21eeae..c534ef72c0 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -40,7 +40,7 @@ proc-macro2 = "1.0.89" example-projects = { workspace = true } -dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false } +dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false } [target.'cfg(target_arch = "wasm32")'.dependencies] # dioxus-sdk = { workspace = true, default-features = false, features = ["system_theme", "window_size", "timing",] } diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 7937f37a3f..a744bcb236 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -1,9 +1,10 @@ use crate::build::{BuildStage, BuildState}; use crate::components::icons::LoadingSpinner; +use crate::dx_components::select::*; use crate::share_code::copy_share_link; +use crate::HotReload; use crate::{Errors, PlaygroundUrls}; use dioxus::prelude::*; -// use dioxus_sdk::utils::timing::use_debounce; use model::api::ApiClient; use model::Project; @@ -14,12 +15,13 @@ pub fn Header( pane_left_width: Signal>, pane_right_width: Signal>, mut show_examples: Signal, - file_name: ReadOnlySignal, + file_name: ReadSignal, ) -> Element { - let build = use_context::(); - let api_client = use_context::>(); - let project = use_context::>(); - let mut errors = use_context::(); + let api_client: Signal = use_context(); + let mut build: BuildState = use_context(); + let mut project: Signal = use_context(); + let mut errors: Errors = use_context(); + let mut hot_reload: HotReload = use_context(); let mut share_btn_text = use_signal(|| "Share"); @@ -31,14 +33,34 @@ pub fn Header( style: if let Some(val) = pane_left_width() { "width:{val}px;" }, // Examples button/menu - button { - id: "dxp-menu-btn", - class: "dxp-ctrl-btn", - class: if show_examples() { "dxp-open" }, - onclick: move |_| show_examples.toggle(), - crate::components::icons::MenuIcon {} + Select:: { + value: Some(project()), + on_value_change: move |example: Option| { + use crate::monaco; + let Some(example) = example else { + return; + }; + + project.set(example.clone()); + build.set_stage(BuildStage::Finished(Ok(example.id()))); + monaco::set_current_model_value(&example.contents()); + hot_reload.set_starting_code(&example.contents()); + }, + SelectTrigger { + {file_name} + } + SelectList { + for (index, example) in example_projects::get_example_projects().iter().enumerate() { + SelectOption:: { + index, + value: example.clone(), + text_value: example.path.clone(), + h3 { {example.path.clone()} } + p { {example.description.clone()} } + } + } + } } - button { class: "dxp-ctrl-btn dxp-file-btn dxp-selected-file", {file_name} } } // Right pane header diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 36105a907d..5f000cd344 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -37,7 +37,7 @@ pub struct PlaygroundUrls { #[component] pub fn Playground( urls: PlaygroundUrls, - share_code: ReadOnlySignal>, + share_code: ReadSignal>, class: Option, ) -> Element { let mut hot_reload = use_context_provider(HotReload::new); @@ -198,23 +198,6 @@ pub fn Playground( file_name: project.read().path.clone(), } div { id: "dxp-lower-half", - div { - id: "dxp-examples-list", - class: if show_examples() { "dxp-open" } else { "" }, - for example in example_projects::get_example_projects().iter() { - button { - class: "dxp-example-project", - onclick: move |_| { - project.set(example.clone()); - build.set_stage(BuildStage::Finished(Ok(example.id()))); - monaco::set_current_model_value(&example.contents()); - hot_reload.set_starting_code(&example.contents()); - }, - h3 { {example.path.clone()} } - p { {example.description.clone()} } - } - } - } components::Panes { pane_left_width, pane_right_width, diff --git a/packages/playground/runner/src/main.rs b/packages/playground/runner/src/main.rs index 6574ca8e51..afe04e3159 100644 --- a/packages/playground/runner/src/main.rs +++ b/packages/playground/runner/src/main.rs @@ -51,7 +51,7 @@ fn DefaultPlayground() -> Element { } #[component] -fn SharePlayground(share_code: ReadOnlySignal>) -> Element { +fn SharePlayground(share_code: ReadSignal>) -> Element { rsx! { Playground { urls: URLS, share_code, class: "playground-container" } } diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index d77165eb46..5f6a9e79bf 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -593,7 +593,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" +source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" dependencies = [ "dioxus", "dioxus-time", @@ -1516,7 +1516,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" +name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" version = "0.1.0" dependencies = [ "dioxus", diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index 7a5c3ec118..5b90650f91 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -2,13 +2,13 @@ [workspace] [package] -name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" +name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" version = "0.1.0" edition = "2024" [dependencies] dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } +dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml index feb660d85c..b8ea63215f 100644 --- a/packages/playground/server/template/Dioxus.toml +++ b/packages/playground/server/template/Dioxus.toml @@ -1,12 +1,12 @@ [application] -name = "5f1689ca-25e2-3fea-96d4-75ad3e26efa9" +name = "015cef34-f8d3-3b3f-913a-d74f0e3ac510" default_platform = "web" out_dir = "dist" asset_dir = "assets" hot_reload = false [web.app] -base_path = "built/5f1689ca-25e2-3fea-96d4-75ad3e26efa9" +base_path = "built/015cef34-f8d3-3b3f-913a-d74f0e3ac510" title = "Dioxus Playground" [web.watcher] diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index cfe5b85452..e0b08e07b7 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" [dependencies] dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } +dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 5cfde7b728..a6f3b11f6e 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -1,5 +1,4 @@ -//! A basic counter example demonstrating signals, -//! event handlers, and basic rendering. +//! The simplest Dioxus app use dioxus::prelude::*; @@ -9,13 +8,7 @@ fn main() { #[component] fn App() -> Element { - let mut count = use_signal(|| 0); - rsx! { - p { "Count: {count*2}" } - div { style: "display: flex;", - button { onclick: move |_| count -= 1, "-" } - button { onclick: move |_| count += 1, "+" } - } + div { "Build cool!" } } } From 375270fd7f44bcb52e3cd043c5bd9e176f21cd8d Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 8 Oct 2025 09:10:41 -0500 Subject: [PATCH 27/58] Fix share feature --- packages/playground/model/src/api.rs | 4 +- packages/playground/model/src/project.rs | 23 +- packages/playground/playground/assets/dxp.css | 817 ++++++++---------- .../playground/src/components/header.rs | 34 +- .../playground/src/components/modal.rs | 61 +- .../src/dx_components/button/style.css | 58 +- packages/playground/playground/src/lib.rs | 55 +- .../playground/playground/src/share_code.rs | 13 +- packages/playground/server/src/share.rs | 3 +- .../playground/server/template/Cargo.lock | 2 +- .../playground/server/template/Cargo.toml | 2 +- 11 files changed, 508 insertions(+), 564 deletions(-) diff --git a/packages/playground/model/src/api.rs b/packages/playground/model/src/api.rs index 40ca844d43..d6c5484d27 100644 --- a/packages/playground/model/src/api.rs +++ b/packages/playground/model/src/api.rs @@ -11,13 +11,13 @@ pub struct ShareProjectReq { /// API response for sharing a project. #[derive(Debug, Serialize, Deserialize)] pub struct ShareProjectRes { - pub id: String, + pub id: uuid::Uuid, } /// API response for requesting a shared project. #[derive(Debug, Serialize, Deserialize)] pub struct GetSharedProjectRes { - pub id: String, + pub id: uuid::Uuid, pub code: String, } diff --git a/packages/playground/model/src/project.rs b/packages/playground/model/src/project.rs index bbe63c7435..ee7733c446 100644 --- a/packages/playground/model/src/project.rs +++ b/packages/playground/model/src/project.rs @@ -13,7 +13,7 @@ pub struct Project { contents: String, pub prebuilt: bool, id: Uuid, - shared_id: Option, + shared_id: Option, } impl Project { @@ -36,6 +36,14 @@ impl Project { self.id } + pub fn shared_id(&self) -> Option { + self.shared_id + } + + pub fn set_shared_id(&mut self, new_shared_id: Uuid) { + self.shared_id = Some(new_shared_id); + } + pub fn contents(&self) -> String { self.contents.clone() } @@ -68,24 +76,25 @@ impl Project { }) } - pub async fn share_project(&mut self, client: &ApiClient) -> Result { + pub async fn share_project( + shared_id: Option, + code: String, + client: &ApiClient, + ) -> Result { // If the project has already been shared, return the share code. // We remove the shared id if the content changes. - if let Some(share_code) = &self.shared_id { + if let Some(share_code) = &shared_id { return Ok(share_code.clone()); } let url = format!("{}/shared", client.server_url); let res = client .post(url) - .json(&ShareProjectReq { - code: self.contents.clone(), - }) + .json(&ShareProjectReq { code }) .send() .await?; let res = res.json::().await?; - self.shared_id = Some(res.id.clone()); Ok(res.id) } diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index 8b1a7b0b27..d5a84938a7 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -1,470 +1,349 @@ -/* Variables and their common uses */ -:root { - /* Light Theme */ - --dxp-bg-light-darker: white; - --dxp-bg-light: white; - --dxp-bg-light-lighter: white; - /* --dxp-bg-light-darker: #C1C6D2; */ - /* --dxp-bg-light: #DCDFE5; - --dxp-bg-light-lighter: #EDEFF2; */ - --dxp-bg-light-lighter-alt: #D6DAE1; - - --dxp-border-light: #b4b4b4; - --dxp-border-light-lighter: #dbdbdc; - /* --dxp-border-light: #15181E; - --dxp-border-light-lighter: #242933; */ - - --dxp-text-light: #131313; - /* --dxp-text-light: #131313; */ - - --dxp-log-info-light: #002fff; - --dxp-log-warn-light: #ff8400; - --dxp-log-error-light: #ff0000; - - /* Dark Theme */ - --dxp-bg-dark-darker: #21252E; - --dxp-bg-dark: #000000; - --dxp-bg-dark-lighter: #454E61; - --dxp-bg-dark-lighter-alt: #363E4D; - - --dxp-border-dark: #5B667D; - --dxp-border-dark-lighter: #8292B2; - - --dxp-text-dark: white; - /* --dxp-text-dark: #dfdfdf; */ - - --dxp-log-info-dark: #4fa2f0; - --dxp-log-warn-dark: #f0b04f; - --dxp-log-error-dark: #f04f4f; - - /* Both Themes */ - --dxp-log-border: #374155; -} - #dxp-playground-root { - border: 1px solid var(--dxp-border-light); - overflow: hidden; + border: 1px solid var(--dxp-border-light); + overflow: hidden; } /* Header */ #dxp-header { - border-bottom: 1px solid var(--dxp-border-light); - background-color: var(--dxp-bg-light-darker); - height: 36px; - display: flex; - flex-direction: row; - margin-left: auto; - margin-right: auto; - width: 100%; + border-bottom: 1px solid var(--dxp-border-light); + background-color: var(--dxp-bg-light-darker); + height: 36px; + display: flex; + flex-direction: row; + margin: 0.5rem; } #dxp-header-left { - flex-grow: 1; - display: flex; - flex-direction: row; - align-items: center; - padding: 8px; + flex-grow: 1; + display: flex; + flex-direction: row; + align-items: center; + gap: 0.5rem; } #dxp-header-left-divider { - flex-grow: 1; + flex-grow: 1; } #dxp-header-right { - flex-grow: 1; - min-width: 100px; - display: flex; - flex-direction: row; - justify-content: end; - align-items: center; - padding: 8px; + flex-grow: 1; + min-width: 100px; + display: flex; + flex-direction: row; + justify-content: end; + align-items: center; + gap: 0.5rem; } - /* Header buttons */ .dxp-ctrl-btn { - height: 25px; - padding: 0px 10px; - border-radius: 5px; - border-style: none; - color: var(--dxp-text-light); - font-family: "Inter", sans-serif; - font-size: 14px; - font-weight: 400; - letter-spacing: -0.06em; - transition: background-color 0.2s ease; + height: 25px; + padding: 0px 10px; + border-radius: 5px; + border-style: none; + color: var(--dxp-text-light); + font-family: "Inter", sans-serif; + font-size: 14px; + font-weight: 400; + letter-spacing: -0.06em; + transition: background-color 0.2s ease; } #dxp-menu-btn { - background-color: var(--dxp-bg-light-lighter); - display: flex; - align-items: center; - justify-content: center; - padding: 5px; - + background-color: var(--dxp-bg-light-lighter); + display: flex; + align-items: center; + justify-content: center; + padding: 5px; } #dxp-menu-btn:hover { - cursor: pointer; - background-color: var(--dxp-bg-light-lighter-alt); + cursor: pointer; + background-color: var(--dxp-bg-light-lighter-alt); } #dxp-menu-btn.dxp-open { - border: 1px solid var(--dxp-border-light-lighter); + border: 1px solid var(--dxp-border-light-lighter); } -#dxp-menu-btn>svg { - color: var(--dxp-text-light); +#dxp-menu-btn > svg { + color: var(--dxp-text-light); } .dxp-ctrl-btn:hover { - cursor: pointer; - background-color: var(--dxp-bg-light-lighter-alt); -} - -#dxp-header-left>.dxp-ctrl-btn:not(:first-child) { - margin-left: 12px; -} - -#dxp-header-right>.dxp-ctrl-btn:not(:last-child) { - margin-right: 12px; -} - -#dxp-run-btn { - background-color: var(--dxp-bg-light-lighter); - color: var(--dxp-text-light); - display: flex; - flex-direction: row; - align-items: center; - justify-items: start; - font-family: "Inter", sans-serif; - font-size: 14px; - font-weight: 400; - letter-spacing: -0.06em; -} - -#dxp-run-btn:not(.disabled) { - background-color: #288AE5; - color: var(--dxp-text-dark); -} - -#dxp-run-btn.disabled:hover { - cursor: not-allowed; -} - -#dxp-run-btn:hover:not(.disabled) { - background-color: #1E68AD; -} - -#dxp-run-btn>svg { - color: var(--dxp-text-light); - height: 16px; - position: relative; - left: -5px; -} - -.dxp-file-btn { - min-width: 100px; - background-color: var(--dxp-bg-light-lighter); -} - -.dxp-selected-file { - border: 1px solid var(--dxp-border-light-lighter); -} - -#dxp-share-btn { - background-color: transparent; -} - -#dxp-share-btn:hover { - text-decoration: underline; -} - -#dxp-examples-list { - width: 200px; - display: none; - background-color: var(--dxp-bg-light-darker); -} - -#dxp-examples-list.dxp-open { - display: block; -} - - -.dxp-example-project { - color: var(--dxp-text-light); - background: inherit; - text-align: left; - cursor: pointer; - width: 100%; - padding: 10px 10px; - margin: 0; - transition: background-color 0.2s ease; - border: none; - border-bottom: 1px solid var(--dxp-bg-light-lighter-alt); -} - -.dxp-example-project:hover { - background-color: var(--dxp-bg-light-lighter-alt); + cursor: pointer; + background-color: var(--dxp-bg-light-lighter-alt); } -.dxp-example-project>h3 { - padding: 0; - margin: 0; - font-family: "Inter", sans-serif; - font-weight: 500; +#dxp-header-left > .dxp-ctrl-btn:not(:first-child) { + margin-left: 12px; } -.dxp-example-project>p { - font-family: "Inter", sans-serif; - font-weight: 300; +#dxp-header-right > .dxp-ctrl-btn:not(:last-child) { + margin-right: 12px; } #dxp-lower-half { - display: flex; - flex-grow: 1; + display: flex; + flex-grow: 1; } /* Panes */ #dxp-panes { - flex-grow: 1; - flex-direction: row; - margin-left: auto; - margin-right: auto; - display: flex; - border-left: 1px solid var(--dxp-border-light); + flex-grow: 1; + flex-direction: row; + margin-left: auto; + margin-right: auto; + display: flex; + border-left: 1px solid var(--dxp-border-light); } #dxp-panes-left { - width: 50%; - min-width: 100px; - background-color: var(--dxp-bg-light); + width: 50%; + min-width: 100px; + background-color: var(--dxp-bg-light); } #dxp-panes-draggable { - width: 3px; - background-color: var(--dxp-border-light); - cursor: col-resize; - user-select: none; + width: 3px; + background-color: var(--dxp-border-light); + cursor: col-resize; + user-select: none; } - #dxp-panes-right { - display: flex; - width: 50%; - min-width: 100px; - background-color: var(--dxp-bg-light-darker); - position: relative; -} - -#dxp-panes-right>p { - color: var(--dxp-text-light); - font-family: "Inter", sans-serif; - user-select: none; - text-align: center; - width: 100%; - height: fit-content; - top: 30%; - position: relative; + display: flex; + width: 50%; + min-width: 100px; + background-color: var(--dxp-bg-light-darker); + position: relative; +} + +#dxp-panes-right > p { + color: var(--dxp-text-light); + font-family: "Inter", sans-serif; + user-select: none; + text-align: center; + width: 100%; + height: fit-content; + top: 30%; + position: relative; } -#dxp-panes-right>#iframe-cover { - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 1; - pointer-events: all; +#dxp-panes-right > #iframe-cover { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 1; + pointer-events: all; } -#dxp-panes-right>#dxp-viewport { - width: 100%; - margin: 10px; - background-color: white; +#dxp-panes-right > #dxp-viewport { + width: 100%; + background-color: var(--primary-color); } #dxp-iframe { - width: 100%; - height: 100%; - border: none; + width: 100%; + height: 100%; + border: none; } -#dxp-panes-right>#dxp-examples-viewport { - padding: 8px; - width: 100%; - height: 100%; +#dxp-panes-right > #dxp-examples-viewport { + padding: 8px; + width: 100%; + height: 100%; } -#dxp-panes-right>#dxp-progress-container { - display: flex; - flex-direction: column; - height: fit-content; - width: 100%; - top: 30%; - position: relative; +#dxp-panes-right > #dxp-progress-container { + display: flex; + flex-direction: column; + height: fit-content; + width: 100%; + top: 30%; + position: relative; } -#dxp-panes-right>#dxp-progress-container>p { - color: var(--dxp-text-light); - font-family: "Inter", sans-serif; - margin-left: auto; - margin-right: auto; - width: 70%; - user-select: none; +#dxp-panes-right > #dxp-progress-container > p { + color: var(--dxp-text-light); + font-family: "Inter", sans-serif; + margin-left: auto; + margin-right: auto; + width: 70%; + user-select: none; } -#dxp-panes-right>#dxp-progress-container>#dxp-progress { - height: 6px; - width: 70%; - margin-left: auto; - margin-right: auto; - background-color: var(--dxp-bg-light-lighter); - border-radius: 5px; - overflow: hidden; +#dxp-panes-right > #dxp-progress-container > #dxp-progress { + height: 6px; + width: 70%; + margin-left: auto; + margin-right: auto; + background-color: var(--dxp-bg-light-lighter); + border-radius: 5px; + overflow: hidden; } -#dxp-panes-right>#dxp-progress-container>#dxp-progress>#dxp-bar { - background: #288AE5; - background: linear-gradient(90deg, rgb(91, 87, 202) 0%, rgba(40, 138, 229, 1) 100%); - height: 100%; +#dxp-panes-right > #dxp-progress-container > #dxp-progress > #dxp-bar { + background: #288ae5; + background: linear-gradient( + 90deg, + rgb(91, 87, 202) 0%, + rgba(40, 138, 229, 1) 100% + ); + height: 100%; } /* Modal */ #dxp-modal-bg { - background-color: rgba(0, 0, 0, 40%); - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - z-index: 100; + background-color: rgba(0, 0, 0, 40%); + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 100; - display: flex; - justify-content: center; - align-items: center; + display: flex; + justify-content: center; + align-items: center; } #dxp-modal { - background-color: var(--dxp-bg-light); - border: 1px solid #000000; - color: var(--dxp-text-light); - border-radius: 5px; - padding: 15px; - margin-bottom: 20vh; + background-color: var(--dxp-bg-light); + border: 1px solid #000000; + color: var(--dxp-text-light); + border-radius: 5px; + padding: 15px; + margin-bottom: 20vh; - font-family: "Inter", sans-serif; - font-weight: 400; + font-family: "Inter", sans-serif; + font-weight: 400; - max-width: 500px; + max-width: 500px; } #dxp-modal-header { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-start; } -#dxp-modal-header>svg { - height: 40px; +#dxp-modal-header > svg { + height: 40px; } #dxp-modal-title { - font-size: 20px; - font-weight: 600; - margin-top: 0px; - margin-bottom: 0px; - margin-left: 10px; + font-size: 20px; + font-weight: 600; + margin-top: 0px; + margin-bottom: 0px; + margin-left: 10px; } #dxp-modal-text { - font-weight: 400; - font-size: 16px; - margin-bottom: 20px; + font-weight: 400; + font-size: 16px; + margin-bottom: 20px; } #dxp-modal-ok-btn { - display: block; - background-color: var(--dxp-bg-light-lighter); - border-radius: 3px; - color: var(--dxp-text-light); - padding: 8px; - - font-weight: 400; - font-size: 14px; - margin-left: auto; + display: block; + background-color: var(--dxp-bg-light-lighter); + border-radius: 3px; + color: var(--dxp-text-light); + padding: 8px; + + font-weight: 400; + font-size: 14px; + margin-left: auto; - border: none; - transition: background-color 0.2s ease; + border: none; + transition: background-color 0.2s ease; } #dxp-modal-ok-btn:hover { - background-color: var(--dxp-bg-light-darker); - cursor: pointer; + background-color: var(--dxp-bg-light-darker); + cursor: pointer; } /* Logs pane */ #logs { - display: flex; - flex-direction: column; - width: 100%; - overflow-y: auto; + display: flex; + flex-direction: column; + width: 100%; + overflow-y: auto; } #logs .log { - padding: 20px 15px; - transition: background-color 0.3s ease; - color: var(--dxp-text-light); - border-bottom: var(--dxp-log-border) 1px solid; + padding: 20px 15px; + transition: background-color 0.3s ease; + color: var(--dxp-text-light); + border-bottom: var(--dxp-log-border) 1px solid; } #logs .log:hover { - background-color: var(--dxp-bg-light); + background-color: var(--dxp-bg-light); } #logs .log .log-level { - font-family: "Inter", sans-serif; - padding-top: 0px; - padding-bottom: 10px; - margin: 0px; + font-family: "Inter", sans-serif; + padding-top: 0px; + padding-bottom: 10px; + margin: 0px; } #logs .log .level-error { - color: var(--dxp-log-error-light); + color: var(--dxp-log-error-light); } #logs .log .level-warn { - color: var(--dxp-log-warn-light); + color: var(--dxp-log-warn-light); } #logs .log .level-info { - color: var(--dxp-log-info-light) + color: var(--dxp-log-info-light); } #logs .log .log-codeblock { - background-color: var(--dxp-bg-light); - padding: 10px; - border-radius: 10px; - border: var(--dxp-border-light) 1px solid; + background-color: var(--dxp-bg-light); + padding: 10px; + border-radius: 10px; + border: var(--dxp-border-light) 1px solid; } #logs .log .log-message, #logs.log.log-span { - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; + font-family: + ui-monospace, + SFMono-Regular, + SF Mono, + Menlo, + Consolas, + Liberation Mono, + monospace; } #logs .log .log-message { - padding: 0px; - margin: 0px; + padding: 0px; + margin: 0px; } #logs .log .log-span { - padding: 0px; - margin: 0px; - font-family: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace; + padding: 0px; + margin: 0px; + font-family: + ui-monospace, + SFMono-Regular, + SF Mono, + Menlo, + Consolas, + Liberation Mono, + monospace; } /* Media Queries */ @@ -508,142 +387,140 @@ } */ @media screen and (prefers-color-scheme: dark) { + #dxp-playground-root { + border-color: var(--dxp-border-dark); + } + + /* Header */ + #dxp-header { + border-bottom-color: var(--dxp-border-dark); + background-color: var(--dxp-bg-dark-darker); + } + + .dxp-ctrl-btn { + color: var(--dxp-text-dark); + } + + #dxp-menu-btn { + background-color: var(--dxp-bg-dark-lighter); + } + + #dxp-menu-btn:hover { + background-color: var(--dxp-bg-dark-lighter-alt); + } + + #dxp-menu-btn.dxp-open { + border: 1px solid var(--dxp-border-dark-lighter); + } + + #dxp-menu-btn > svg { + color: var(--dxp-text-dark); + } + + #dxp-run-btn { + color: var(--dxp-text-dark); + background-color: var(--dxp-bg-dark-lighter); + } + + #dxp-run-btn > svg { + color: var(--dxp-text-dark); + } + + .dxp-ctrl-btn:hover { + cursor: pointer; + background-color: var(--dxp-bg-dark-lighter-alt); + } + + .dxp-file-btn { + background-color: var(--dxp-bg-dark-lighter); + } + + .dxp-selected-file { + border-color: var(--dxp-border-dark-lighter); + } + + /* Examples */ + #dxp-examples-list { + background-color: var(--dxp-bg-dark-darker); + } + + .dxp-example-project { + color: var(--dxp-text-dark); + border-bottom: 1px solid var(--dxp-bg-dark-lighter-alt); + } + + .dxp-example-project:hover { + background-color: var(--dxp-bg-dark-lighter-alt); + } + + /* Panes */ + + #dxp-panes { + border-left-color: var(--dxp-border-dark); + } + + #dxp-panes-left { + background-color: var(--dxp-bg-dark); + } + + #dxp-panes-draggable { + background-color: var(--dxp-border-dark); + } + + #dxp-panes-right { + background-color: var(--dxp-bg-dark-darker); + } + + #dxp-panes-right > p, + #dxp-panes-right > #dxp-progress-container > p { + color: var(--dxp-text-dark); + } + + #dxp-panes-right > #dxp-progress-container > #dxp-progress { + background-color: var(--dxp-bg-dark-lighter); + } + + /* Modal */ + + #dxp-modal { + background-color: var(--dxp-bg-dark); + border: 1px solid var(--dxp-border-dark); + color: var(--dxp-text-dark); + } + + #dxp-modal-ok-btn { + background-color: var(--dxp-bg-dark-lighter); + color: var(--dxp-text-dark); + } + + #dxp-modal-ok-btn:hover { + background-color: var(--dxp-bg-dark-lighter-alt); + } - #dxp-playground-root { - border-color: var(--dxp-border-dark); - } - - /* Header */ - #dxp-header { - border-bottom-color: var(--dxp-border-dark); - background-color: var(--dxp-bg-dark-darker); - } - - .dxp-ctrl-btn { - color: var(--dxp-text-dark); - } - - #dxp-menu-btn { - background-color: var(--dxp-bg-dark-lighter); - } - - #dxp-menu-btn:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - #dxp-menu-btn.dxp-open { - border: 1px solid var(--dxp-border-dark-lighter); - } - - #dxp-menu-btn>svg { - color: var(--dxp-text-dark); - } - - #dxp-run-btn { - color: var(--dxp-text-dark); - background-color: var(--dxp-bg-dark-lighter); - } - - #dxp-run-btn>svg { - color: var(--dxp-text-dark); - } - - .dxp-ctrl-btn:hover { - cursor: pointer; - background-color: var(--dxp-bg-dark-lighter-alt); - } - - .dxp-file-btn { - background-color: var(--dxp-bg-dark-lighter); - } - - .dxp-selected-file { - border-color: var(--dxp-border-dark-lighter); - } - - /* Examples */ - #dxp-examples-list { - background-color: var(--dxp-bg-dark-darker); - } - - .dxp-example-project { - color: var(--dxp-text-dark); - border-bottom: 1px solid var(--dxp-bg-dark-lighter-alt); - } - - .dxp-example-project:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - - /* Panes */ - - #dxp-panes { - border-left-color: var(--dxp-border-dark); - } - - #dxp-panes-left { - background-color: var(--dxp-bg-dark); - } - - #dxp-panes-draggable { - background-color: var(--dxp-border-dark); - } - - #dxp-panes-right { - background-color: var(--dxp-bg-dark-darker); - } - - #dxp-panes-right>p, - #dxp-panes-right>#dxp-progress-container>p { - color: var(--dxp-text-dark); - } - - #dxp-panes-right>#dxp-progress-container>#dxp-progress { - background-color: var(--dxp-bg-dark-lighter); - } - - /* Modal */ - - #dxp-modal { - background-color: var(--dxp-bg-dark); - border: 1px solid var(--dxp-border-dark); - color: var(--dxp-text-dark); - } - - #dxp-modal-ok-btn { - background-color: var(--dxp-bg-dark-lighter); - color: var(--dxp-text-dark); - } - - #dxp-modal-ok-btn:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - /* Logs */ - - #logs .log { - color: var(--dxp-text-dark); - } - - #logs .log:hover { - background-color: var(--dxp-bg-dark); - } - - #logs .log .level-error { - color: var(--dxp-log-error-dark); - } - - #logs .log .level-warn { - color: var(--dxp-log-warn-dark); - } - - #logs .log .level-info { - color: var(--dxp-log-info-dark) - } - - #logs .log .log-codeblock { - background-color: var(--dxp-bg-dark); - border-color: var(--dxp-border-dark); - } + /* Logs */ + + #logs .log { + color: var(--dxp-text-dark); + } + + #logs .log:hover { + background-color: var(--dxp-bg-dark); + } + + #logs .log .level-error { + color: var(--dxp-log-error-dark); + } + + #logs .log .level-warn { + color: var(--dxp-log-warn-dark); + } + + #logs .log .level-info { + color: var(--dxp-log-info-dark); + } + + #logs .log .log-codeblock { + background-color: var(--dxp-bg-dark); + border-color: var(--dxp-border-dark); + } } diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index a744bcb236..5b2084a547 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -1,5 +1,6 @@ use crate::build::{BuildStage, BuildState}; use crate::components::icons::LoadingSpinner; +use crate::dx_components::button::*; use crate::dx_components::select::*; use crate::share_code::copy_share_link; use crate::HotReload; @@ -55,8 +56,21 @@ pub fn Header( index, value: example.clone(), text_value: example.path.clone(), - h3 { {example.path.clone()} } - p { {example.description.clone()} } + div { + display: "flex", + flex_direction: "column", + align_items: "left", + padding: "0.25rem", + h3 { + margin: "0", + margin_bottom: ".25rem", + {example.path.clone()} + } + p { + margin: "0", + {example.description.clone()} + } + } } } } @@ -69,9 +83,8 @@ pub fn Header( style: if let Some(val) = pane_right_width() { "width:{val}px;" } else { "".to_string() }, // Share button - button { - id: "dxp-share-btn", - class: "dxp-ctrl-btn", + Button { + variant: ButtonVariant::Secondary, onclick: move |_| async move { share_btn_text.set("Sharing..."); match copy_share_link(&api_client(), project, urls.location).await { @@ -93,10 +106,13 @@ pub fn Header( // Run button - button { - id: "dxp-run-btn", - class: "dxp-ctrl-btn", - class: if build.stage().is_running() { "disabled" }, + Button { + variant: ButtonVariant::Outline, + "data-disabled": build.stage().is_running(), + display: "flex", + flex_direction: "row", + align_items: "center", + gap: "0.5rem", onclick: move |_| { on_rebuild.call(()); }, diff --git a/packages/playground/playground/src/components/modal.rs b/packages/playground/playground/src/components/modal.rs index 085f9f244c..58e5d62153 100644 --- a/packages/playground/playground/src/components/modal.rs +++ b/packages/playground/playground/src/components/modal.rs @@ -1,35 +1,54 @@ use crate::dx_components::dialog::{DialogContent, DialogDescription, DialogRoot, DialogTitle}; use dioxus::prelude::*; +#[derive(Clone)] +struct ModalContext { + open: Signal, + on_ok: EventHandler, +} + +#[component] +pub fn Modal(on_ok: EventHandler, open: ReadSignal, children: Element) -> Element { + let mut internal_open = use_signal(|| false); + use_effect(move || internal_open.set(open())); + use_context_provider(move || ModalContext { + open: internal_open, + on_ok, + }); + rsx! { + DialogRoot { + open: internal_open(), + on_open_change: move |_| { + on_ok(()); + }, + {children} + } + } +} + #[component] -pub fn Modal( +pub fn ModalContent( icon: Element, title: String, text: String, ok_text: Option, - on_ok: EventHandler, ) -> Element { - let ok_text = ok_text.unwrap_or("Ok".to_string()); - let mut open = use_signal(|| true); - + let ModalContext { open, on_ok } = use_context(); rsx! { - DialogRoot { - open: open(), - DialogContent { - button { - class: "dialog-close", - r#type: "button", - aria_label: "Close", - tabindex: if open() { "0" } else { "-1" }, - onclick: move |_| open.set(false), - "×" - } - DialogTitle { - {icon} - "{title}" - } - DialogDescription { "{text}" } + DialogContent { + button { + class: "dialog-close", + r#type: "button", + aria_label: "Close", + tabindex: if open() { "0" } else { "-1" }, + onclick: move |_| on_ok(()), + "×" + } + DialogTitle { + {icon} + "{title}" } + DialogDescription { "{text}" } } } } diff --git a/packages/playground/playground/src/dx_components/button/style.css b/packages/playground/playground/src/dx_components/button/style.css index 1a02c70ae5..e8e7e2fb91 100644 --- a/packages/playground/playground/src/dx_components/button/style.css +++ b/packages/playground/playground/src/dx_components/button/style.css @@ -1,54 +1,62 @@ .button { - padding: 8px 18px; - border-radius: 0.5rem; - border: none; - cursor: pointer; - font-size: 1rem; - transition: background-color 0.2s ease, color 0.2s ease; + padding: 8px 18px; + border-radius: 0.5rem; + border: none; + cursor: pointer; + font-size: 1rem; + transition: + background-color 0.2s ease, + color 0.2s ease; } .button:focus-visible { - box-shadow: 0 0 0 2px var(--focused-border-color); + box-shadow: 0 0 0 2px var(--focused-border-color); } .button[data-style="primary"] { - background-color: var(--secondary-color-2); - color: var(--primary-color); + background-color: var(--secondary-color-2); + color: var(--primary-color); } .button[data-style="primary"]:hover { - background-color: var(--secondary-color-1); + background-color: var(--secondary-color-1); } .button[data-style="secondary"] { - background-color: var(--primary-color-5); - color: var(--secondary-color-1); + background-color: var(--primary-color-5); + color: var(--secondary-color-1); } .button[data-style="secondary"]:hover { - background-color: var(--primary-color-4); + background-color: var(--primary-color-4); } .button[data-style="ghost"] { - background-color: transparent; - color: var(--secondary-color-4); + background-color: transparent; + color: var(--secondary-color-4); } .button[data-style="ghost"]:hover { - background-color: var(--primary-color-5); - color: var(--secondary-color-1); + background-color: var(--primary-color-5); + color: var(--secondary-color-1); } .button[data-style="outline"] { - border: 1px solid var(--primary-color-6); - background-color: var(--light, var(--primary-color)) - var(--dark, var(--primary-color-3)); - color: var(--secondary-color-4); + border: 1px solid var(--primary-color-6); + background-color: var(--light, var(--primary-color)) + var(--dark, var(--primary-color-3)); + color: var(--secondary-color-4); } .button[data-style="outline"]:hover { - background-color: var(--primary-color-4); + background-color: var(--primary-color-4); } .button[data-style="destructive"] { - background-color: var(--primary-error-color); - color: var(--contrast-error-color); + background-color: var(--primary-error-color); + color: var(--contrast-error-color); } .button[data-style="destructive"]:hover { - background-color: var(--secondary-error-color); + background-color: var(--secondary-error-color); +} + +.button[data-disabled="true"] { + background-color: var(--primary-color-6); + color: var(--secondary-color-5); + cursor: not-allowed; } diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 5f000cd344..e93b76d60c 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -1,4 +1,4 @@ -use build::{start_build, BuildStage, BuildState}; +use build::{start_build, BuildState}; use components::icons::Warning; use dioxus::logger::tracing::error; use dioxus::prelude::*; @@ -50,7 +50,7 @@ pub fn Playground( // Default to the welcome project. // Project dirty determines whether the Rust-project is synced with the project in the editor. let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); - let mut build = use_context_provider(|| BuildState::new(&project.read())); + let build = use_context_provider(|| BuildState::new(&project.read())); let mut project_dirty = use_signal(|| false); use_effect(move || { if project_dirty() && monaco_ready() { @@ -162,30 +162,33 @@ pub fn Playground( } // Share warning - if show_share_warning() { - components::Modal { - icon: rsx! { - Warning {} - }, - title: "Do you trust this code?", - text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", - ok_text: "I understand", - on_ok: move |_| show_share_warning.set(false), - } - } + // if show_share_warning() { + // components::Modal { + // icon: rsx! { + // Warning {} + // }, + // title: "Do you trust this code?", + // text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", + // ok_text: "I understand", + // on_ok: move |_| show_share_warning.set(false), + // } + // } // Show errors one at a time. - if let Some(error) = errors.first() { - components::Modal { - icon: rsx! { - Warning {} - }, - title: "{error.0}", - text: "{error.1}", - on_ok: move |_| { - errors.pop(); - }, - } + components::Modal { + on_ok: move |_| { + errors.pop(); + }, + open: !errors.errors.is_empty(), + if let Some((title, text)) = errors.last() { + components::ModalContent { + icon: rsx! { + Warning {} + }, + title, + text, + } + }, } // Playground UI @@ -256,6 +259,10 @@ impl Errors { self.errors.first().map(|x| x.clone()) } + pub fn last(&self) -> Option<(String, String)> { + self.errors.last().map(|x| x.clone()) + } + pub fn pop(&mut self) -> Option<(String, String)> { self.errors.pop() } diff --git a/packages/playground/playground/src/share_code.rs b/packages/playground/playground/src/share_code.rs index 255e0becb7..79a5c3e229 100644 --- a/packages/playground/playground/src/share_code.rs +++ b/packages/playground/playground/src/share_code.rs @@ -1,4 +1,4 @@ -use dioxus::signals::{Signal, WritableExt}; +use dioxus::signals::{ReadableExt, Signal, WritableExt}; use dioxus_document::eval; use model::{api::ApiClient, AppError, Project}; @@ -8,9 +8,16 @@ pub async fn copy_share_link( mut project: Signal, location: &str, ) -> Result<(), AppError> { - let share_code = project.write().share_project(api_client).await?; + let read_project = project.read(); + let shared_id = read_project.shared_id(); + let code = read_project.contents(); + // Drop the lock before running any async code. + drop(read_project); + let share_code = Project::share_project(shared_id, code, api_client).await?; - let formatted = format!("{}/shared/{}", location, share_code); + project.write().set_shared_id(share_code); + + let formatted = format!("{}/shared/{}", location, share_code.as_simple()); let e = eval( r#" const data = await dioxus.recv(); diff --git a/packages/playground/server/src/share.rs b/packages/playground/server/src/share.rs index 5df639ac49..8bd9297dbe 100644 --- a/packages/playground/server/src/share.rs +++ b/packages/playground/server/src/share.rs @@ -57,6 +57,7 @@ pub mod gists { use reqwest::{StatusCode, header}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; + use uuid::Uuid; const GISTS_URL_PREFIX: &str = "https://api.github.com/gists"; const GITHUB_USER_AGENT: &str = "Dioxus Playground"; @@ -95,7 +96,7 @@ pub mod gists { #[derive(Debug, Serialize, Deserialize)] pub struct Gist { - pub id: String, + pub id: Uuid, pub files: HashMap, } diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 5f6a9e79bf..114c057c06 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -593,7 +593,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" +source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" dependencies = [ "dioxus", "dioxus-time", diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index 5b90650f91..e9c275bb1c 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" [dependencies] dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" From 3b04217d5c6d2be5a0410179764231af8746ad85 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 8 Oct 2025 11:38:19 -0500 Subject: [PATCH 28/58] fix loading shared projects --- Cargo.lock | 1 + packages/playground/playground/Cargo.toml | 1 + packages/playground/playground/assets/dxp.css | 2 +- .../playground/src/components/header.rs | 4 +- packages/playground/playground/src/lib.rs | 31 +- .../playground/playground/src/share_code.rs | 5 +- packages/playground/runner/src/main.rs | 13 +- packages/playground/server/src/main.rs | 4 +- .../playground/server/template/Cargo.lock | 1302 ++++++++++++++--- .../playground/server/template/Cargo.toml | 2 +- .../playground/server/template/Dioxus.toml | 4 +- .../playground/server/template/src/main.rs | 2 +- packages/playground/server/test.rs | 44 - 13 files changed, 1100 insertions(+), 315 deletions(-) delete mode 100644 packages/playground/server/test.rs diff --git a/Cargo.lock b/Cargo.lock index 68a2543048..df5d1a5be5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2101,6 +2101,7 @@ dependencies = [ "serde_json", "syn 2.0.106", "thiserror 2.0.17", + "tracing", "uuid", "wasm-bindgen", ] diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index c534ef72c0..ab4ca6ba8f 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -41,6 +41,7 @@ proc-macro2 = "1.0.89" example-projects = { workspace = true } dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false } +tracing = "0.1.41" [target.'cfg(target_arch = "wasm32")'.dependencies] # dioxus-sdk = { workspace = true, default-features = false, features = ["system_theme", "window_size", "timing",] } diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index d5a84938a7..5a1e10f44d 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -142,7 +142,7 @@ #dxp-panes-right > #dxp-viewport { width: 100%; - background-color: var(--primary-color); + background-color: white; } #dxp-iframe { diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 5b2084a547..8fe3f4eed1 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -88,7 +88,9 @@ pub fn Header( onclick: move |_| async move { share_btn_text.set("Sharing..."); match copy_share_link(&api_client(), project, urls.location).await { - Ok(()) => share_btn_text.set("Link Copied!"), + Ok(()) => { + share_btn_text.set("Link Copied!"); + }, Err(error) => { share_btn_text.set("Error!"); errors diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index e93b76d60c..4201775c03 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -50,7 +50,7 @@ pub fn Playground( // Default to the welcome project. // Project dirty determines whether the Rust-project is synced with the project in the editor. let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); - let build = use_context_provider(|| BuildState::new(&project.read())); + let mut build = use_context_provider(|| BuildState::new(&project.read())); let mut project_dirty = use_signal(|| false); use_effect(move || { if project_dirty() && monaco_ready() { @@ -70,6 +70,7 @@ pub fn Playground( show_share_warning.set(true); project_dirty.set(true); project.set(shared_project); + build.reset(); } }); } @@ -120,7 +121,8 @@ pub fn Playground( // Construct the full URL to the built project. let built_page_url = use_memo(move || { - let prebuilt_id = project.read().prebuilt.then_some(project.read().id()); + let project = project.read(); + let prebuilt_id = project.prebuilt.then_some(project.id()); let local_id = build.stage().finished_id(); let id = local_id.or(prebuilt_id)?; Some(format!("{}/built/{}", urls.server, id)) @@ -162,17 +164,20 @@ pub fn Playground( } // Share warning - // if show_share_warning() { - // components::Modal { - // icon: rsx! { - // Warning {} - // }, - // title: "Do you trust this code?", - // text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", - // ok_text: "I understand", - // on_ok: move |_| show_share_warning.set(false), - // } - // } + components::Modal { + on_ok: move |_| show_share_warning.set(false), + open: show_share_warning(), + if show_share_warning() { + components::ModalContent { + icon: rsx! { + Warning {} + }, + title: "Do you trust this code?", + text: "Anyone can share their project. Verify that nothing malicious has been included before running this project.", + ok_text: "I understand", + } + } + } // Show errors one at a time. components::Modal { diff --git a/packages/playground/playground/src/share_code.rs b/packages/playground/playground/src/share_code.rs index 79a5c3e229..01bf55359c 100644 --- a/packages/playground/playground/src/share_code.rs +++ b/packages/playground/playground/src/share_code.rs @@ -1,4 +1,4 @@ -use dioxus::signals::{ReadableExt, Signal, WritableExt}; +use dioxus::prelude::*; use dioxus_document::eval; use model::{api::ApiClient, AppError, Project}; @@ -25,7 +25,8 @@ pub async fn copy_share_link( "#, ); - e.send(formatted)?; + e.send(&formatted)?; + router().push(formatted); Ok(()) } diff --git a/packages/playground/runner/src/main.rs b/packages/playground/runner/src/main.rs index afe04e3159..ab7ac3e02b 100644 --- a/packages/playground/runner/src/main.rs +++ b/packages/playground/runner/src/main.rs @@ -23,10 +23,10 @@ const MAIN_CSS: Asset = asset!("/src/main.css"); #[derive(Routable, PartialEq, Clone)] enum Route { - #[route("/")] + #[route("/", PlaygroundRoute)] DefaultPlayground {}, - #[route("/shared/:share_code")] + #[route("/shared/:share_code", PlaygroundRoute)] SharePlayground { share_code: String }, } @@ -44,14 +44,7 @@ fn App() -> Element { } #[component] -fn DefaultPlayground() -> Element { - rsx! { - Playground { urls: URLS, class: "playground-container" } - } -} - -#[component] -fn SharePlayground(share_code: ReadSignal>) -> Element { +fn PlaygroundRoute(share_code: ReadSignal>) -> Element { rsx! { Playground { urls: URLS, share_code, class: "playground-container" } } diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 7280bdbebf..650b17e4d4 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -25,9 +25,9 @@ mod ws; /// Rate limiter configuration. /// How many requests each user should get within a time period. -const REQUESTS_PER_INTERVAL: u64 = 600; +const REQUESTS_PER_INTERVAL: u64 = 60; /// The period of time after the request limit resets. -const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(60); +const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(1); #[tokio::main] async fn main() { diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 114c057c06..243730b1c1 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -26,6 +26,34 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -37,12 +65,82 @@ dependencies = [ "syn", ] +[[package]] +name = "async-tungstenite" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee88b4c88ac8c9ea446ad43498955750a4bbe64c4392f21ccfe5d952865e318f" +dependencies = [ + "atomic-waker", + "futures-core", + "futures-io", + "futures-task", + "futures-util", + "log", + "pin-project-lite", + "tungstenite", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "axum" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" +dependencies = [ + "axum-core", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "itoa", + "matchit", + "memchr", + "mime", + "multer", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.76" @@ -91,11 +189,30 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +dependencies = [ + "serde", +] + +[[package]] +name = "cc" +version = "1.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +dependencies = [ + "find-msvc-tools", + "shlex", +] [[package]] name = "cesu8" @@ -103,12 +220,39 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + [[package]] name = "cfg-if" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "charset" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" +dependencies = [ + "base64", + "encoding_rs", +] + [[package]] name = "ciborium" version = "0.2.2" @@ -148,8 +292,8 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize-macro", "serde", @@ -157,8 +301,8 @@ dependencies = [ [[package]] name = "const-serialize-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "quote", @@ -167,15 +311,15 @@ dependencies = [ [[package]] name = "const-str" -version = "0.6.4" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451d0640545a0553814b4c646eb549343561618838e9b42495f466131fe3ad49" +checksum = "f4d34b8f066904ed7cfa4a6f9ee96c3214aa998cb44b69ca20bd2054f47402ed" [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -191,6 +335,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "content_disposition" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc14a88e1463ddd193906285abe5c360c7e8564e05ccc5d501755f7fbc9ca9c" +dependencies = [ + "charset", +] + [[package]] name = "convert_case" version = "0.8.0" @@ -200,6 +353,35 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -209,12 +391,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - [[package]] name = "crunchy" version = "0.2.4" @@ -265,20 +441,6 @@ dependencies = [ "syn", ] -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - [[package]] name = "data-encoding" version = "2.9.0" @@ -294,6 +456,27 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "digest" version = "0.10.7" @@ -306,8 +489,8 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -333,32 +516,37 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ + "dioxus-cli-config", + "http", + "infer", "jni", "js-sys", "manganis-core", "ndk", "ndk-context", "ndk-sys", + "percent-encoding", "thiserror 2.0.17", + "tokio", "wasm-bindgen-futures", "web-sys", ] [[package]] name = "dioxus-cli-config" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "quote", @@ -366,14 +554,15 @@ dependencies = [ [[package]] name = "dioxus-config-macros" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "dioxus-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ + "anyhow", "const_format", "dioxus-core-types", "futures-channel", @@ -392,8 +581,8 @@ dependencies = [ [[package]] name = "dioxus-core-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case", "dioxus-rsx", @@ -404,13 +593,13 @@ dependencies = [ [[package]] name = "dioxus-core-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "dioxus-devtools" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -427,8 +616,8 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "serde", @@ -437,8 +626,8 @@ dependencies = [ [[package]] name = "dioxus-document" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -447,7 +636,7 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "serde", "serde_json", "tracing", @@ -455,62 +644,102 @@ dependencies = [ [[package]] name = "dioxus-fullstack" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" -dependencies = [ +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +dependencies = [ + "anyhow", + "async-stream", + "async-tungstenite", + "axum", + "axum-core", "base64", "bytes", "ciborium", + "const-str", + "const_format", + "content_disposition", + "derive_more", + "dioxus-asset-resolver", + "dioxus-cli-config", "dioxus-core", - "dioxus-devtools", - "dioxus-document", - "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol", - "dioxus-history", - "dioxus-web", - "dioxus_server_macro", + "dioxus-fullstack-core", + "dioxus-fullstack-macro", + "dioxus-hooks", + "dioxus-html", + "dioxus-signals", + "form_urlencoded", + "futures", "futures-channel", "futures-util", - "generational-box", + "gloo-net", + "headers", "http", + "http-body", + "http-body-util", + "js-sys", + "mime", + "pin-project", + "reqwest", + "rustversion", + "send_wrapper", "serde", - "server_fn", + "serde_json", + "serde_qs", + "serde_urlencoded", + "thiserror 2.0.17", + "tokio-util", "tracing", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", "web-sys", + "xxhash-rust", ] [[package]] -name = "dioxus-fullstack-hooks" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +name = "dioxus-fullstack-core" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ + "anyhow", + "axum-core", + "base64", + "ciborium", "dioxus-core", "dioxus-document", - "dioxus-fullstack-protocol", "dioxus-history", "dioxus-hooks", "dioxus-signals", "futures-channel", "futures-util", + "generational-box", + "http", + "inventory", "serde", + "serde_json", + "thiserror 2.0.17", + "tracing", ] [[package]] -name = "dioxus-fullstack-protocol" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +name = "dioxus-fullstack-macro" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ - "base64", - "ciborium", - "dioxus-core", - "serde", - "tracing", + "const_format", + "convert_case", + "proc-macro2", + "quote", + "syn", + "xxhash-rust", ] [[package]] name = "dioxus-history" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "tracing", @@ -518,8 +747,8 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-signals", @@ -534,10 +763,11 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "async-trait", + "bytes", "dioxus-core", "dioxus-core-macro", "dioxus-core-types", @@ -546,17 +776,18 @@ dependencies = [ "enumset", "euclid", "futures-channel", + "futures-util", "generational-box", "keyboard-types", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustversion", "tracing", ] [[package]] name = "dioxus-html-internal-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case", "proc-macro2", @@ -566,11 +797,11 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "js-sys", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustc-hash 2.1.1", "sledgehammer_bindgen", "sledgehammer_utils", @@ -581,8 +812,8 @@ dependencies = [ [[package]] name = "dioxus-logger" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "tracing", @@ -604,8 +835,8 @@ dependencies = [ [[package]] name = "dioxus-router" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -623,8 +854,8 @@ dependencies = [ [[package]] name = "dioxus-router-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "base16", "digest", @@ -637,8 +868,8 @@ dependencies = [ [[package]] name = "dioxus-rsx" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -648,8 +879,8 @@ dependencies = [ [[package]] name = "dioxus-signals" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "futures-channel", @@ -663,8 +894,8 @@ dependencies = [ [[package]] name = "dioxus-stores" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-signals", @@ -673,8 +904,8 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case", "proc-macro2", @@ -695,17 +926,14 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ - "async-trait", "dioxus-cli-config", "dioxus-core", "dioxus-core-types", "dioxus-devtools", "dioxus-document", - "dioxus-fullstack-hooks", - "dioxus-fullstack-protocol", "dioxus-history", "dioxus-html", "dioxus-interpreter-js", @@ -715,37 +943,37 @@ dependencies = [ "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustc-hash 2.1.1", + "send_wrapper", "serde", "serde-wasm-bindgen", "serde_json", "tracing", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", ] [[package]] -name = "dioxus_server_macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "server_fn_macro", "syn", ] [[package]] -name = "displaydoc" -version = "0.2.5" +name = "document-features" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" dependencies = [ - "proc-macro2", - "quote", - "syn", + "litrs", ] [[package]] @@ -754,6 +982,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "enumset" version = "1.1.10" @@ -788,7 +1025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -800,6 +1037,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + [[package]] name = "fnv" version = "1.0.7" @@ -906,8 +1149,8 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "parking_lot", "tracing", @@ -923,6 +1166,19 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + [[package]] name = "getrandom" version = "0.3.3" @@ -930,9 +1186,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.7+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -999,15 +1257,33 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" [[package]] -name = "hashbrown" -version = "0.16.0" +name = "headers" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http", +] [[package]] name = "http" @@ -1020,12 +1296,103 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "icu_collections" version = "2.0.0" @@ -1146,7 +1513,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "inventory" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +dependencies = [ + "rustversion", ] [[package]] @@ -1160,6 +1545,22 @@ dependencies = [ "libc", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1215,8 +1616,8 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "lazy_static" @@ -1252,13 +1653,18 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +[[package]] +name = "litrs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" + [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] @@ -1274,6 +1680,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "macro-string" version = "0.1.4" @@ -1287,8 +1699,8 @@ dependencies = [ [[package]] name = "manganis" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize", "manganis-core", @@ -1297,8 +1709,8 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -1308,8 +1720,8 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dunce", "macro-string", @@ -1328,6 +1740,12 @@ dependencies = [ "regex-automata", ] +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.7.6" @@ -1352,6 +1770,22 @@ dependencies = [ "libc", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -1372,6 +1806,23 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + [[package]] name = "ndk" version = "0.9.0" @@ -1456,9 +1907,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -1466,15 +1917,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -1516,7 +1967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" +name = "play-e05e67a4-8c15-35c2-bfba-94314ad0190e" version = "0.1.0" dependencies = [ "dioxus", @@ -1581,6 +2032,77 @@ dependencies = [ "version_check", ] +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.1", + "rustls", + "socket2", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" +dependencies = [ + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand", + "ring", + "rustc-hash 2.1.1", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.41" @@ -1622,7 +2144,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom", + "getrandom 0.3.3", ] [[package]] @@ -1633,9 +2155,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ "bitflags", ] @@ -1657,6 +2179,64 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64", + "bytes", + "cookie", + "cookie_store", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -1671,18 +2251,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustc_version" -version = "0.4.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" @@ -1694,7 +2265,42 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.1", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", ] [[package]] @@ -1724,12 +2330,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" - [[package]] name = "send_wrapper" version = "0.6.0" @@ -1794,72 +2394,37 @@ dependencies = [ ] [[package]] -name = "serde_qs" -version = "0.15.0" +name = "serde_path_to_error" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" dependencies = [ - "percent-encoding", + "itoa", "serde", - "thiserror 2.0.17", + "serde_core", ] [[package]] -name = "server_fn" -version = "0.8.3" +name = "serde_qs" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27fbd25ecc066481e383e2ed62ab2480e708aa3fe46cba36e95f58e61dfd04" +checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" dependencies = [ - "base64", - "bytes", - "const-str", - "const_format", - "dashmap", - "futures", - "gloo-net", - "http", - "js-sys", - "pin-project-lite", - "rustc_version", - "rustversion", - "send_wrapper", + "percent-encoding", "serde", - "serde_json", - "serde_qs", - "server_fn_macro_default", "thiserror 2.0.17", - "throw_error", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "xxhash-rust", -] - -[[package]] -name = "server_fn_macro" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d530c872590473016016679c94e3bddf47372941fc924f687ffd11a1778a71" -dependencies = [ - "const_format", - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn", - "xxhash-rust", ] [[package]] -name = "server_fn_macro_default" -version = "0.8.3" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca7abc92ed696648275ed9ff171131a83d571af11748593dc2e6eb6a4e22a5b9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "server_fn_macro", - "syn", + "form_urlencoded", + "itoa", + "ryu", + "serde", ] [[package]] @@ -1893,6 +2458,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" version = "0.4.11" @@ -1944,6 +2515,22 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1952,8 +2539,8 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "subsecond" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "js-sys", "libc", @@ -1970,12 +2557,18 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "serde", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "2.0.106" @@ -1987,6 +2580,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -2047,15 +2649,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "throw_error" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41e42a6afdde94f3e656fae18f837cb9bbe500a5ac5de325b09f3ec05b9c28e3" -dependencies = [ - "pin-project-lite", -] - [[package]] name = "time" version = "0.3.44" @@ -2063,6 +2656,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", + "itoa", "js-sys", "num-conv", "powerfmt", @@ -2097,6 +2691,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.47.1" @@ -2104,11 +2713,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", + "bytes", "io-uring", "libc", "mio", "pin-project-lite", "slab", + "socket2", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", ] [[package]] @@ -2141,6 +2777,51 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.41" @@ -2198,6 +2879,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tungstenite" version = "0.27.0" @@ -2217,9 +2904,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" @@ -2239,6 +2932,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.7" @@ -2263,6 +2962,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "uuid" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "version_check" version = "0.9.5" @@ -2279,6 +2988,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "warnings" version = "0.2.1" @@ -2419,20 +3137,39 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi-util" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -2443,6 +3180,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -2454,9 +3200,18 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] @@ -2485,13 +3240,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -2504,6 +3276,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -2516,6 +3294,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -2528,12 +3312,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -2546,6 +3342,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -2558,6 +3360,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -2570,6 +3378,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -2582,6 +3396,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + [[package]] name = "winnow" version = "0.7.13" @@ -2674,6 +3494,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.2" @@ -2709,5 +3535,5 @@ dependencies = [ [[patch.unused]] name = "dioxus-dx-wire-format" -version = "0.7.0-rc.0" -source = "git+https://github.com/DioxusLabs/dioxus#6cfe64209a5fd5ba72335b328b35498f7bf95e19" +version = "0.7.0-rc.1" +source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index e9c275bb1c..643dc50289 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -2,7 +2,7 @@ [workspace] [package] -name = "play-015cef34-f8d3-3b3f-913a-d74f0e3ac510" +name = "play-e05e67a4-8c15-35c2-bfba-94314ad0190e" version = "0.1.0" edition = "2024" diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml index b8ea63215f..1a6e59527a 100644 --- a/packages/playground/server/template/Dioxus.toml +++ b/packages/playground/server/template/Dioxus.toml @@ -1,12 +1,12 @@ [application] -name = "015cef34-f8d3-3b3f-913a-d74f0e3ac510" +name = "e05e67a4-8c15-35c2-bfba-94314ad0190e" default_platform = "web" out_dir = "dist" asset_dir = "assets" hot_reload = false [web.app] -base_path = "built/015cef34-f8d3-3b3f-913a-d74f0e3ac510" +base_path = "built/e05e67a4-8c15-35c2-bfba-94314ad0190e" title = "Dioxus Playground" [web.watcher] diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index a6f3b11f6e..538ea6c016 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -9,6 +9,6 @@ fn main() { #[component] fn App() -> Element { rsx! { - div { "Build cool!" } + div { "Build what is this stuff!" } } } diff --git a/packages/playground/server/test.rs b/packages/playground/server/test.rs deleted file mode 100644 index e4dbd346f6..0000000000 --- a/packages/playground/server/test.rs +++ /dev/null @@ -1,44 +0,0 @@ -// From https://github.com/rust-lang/rust/issues/132558 -//#![recursion_limit = "10"] - -trait S { - type Child: S; -} - -impl S for (X, X) { - // Recursing "inwards" here using `X::Child` seems to be - // important. E.g. if I instead define - // - //type Child = ((X, X), (X, X)); - // - // which is just as exponential, but not recursive, then the compiler again - // gives the correct "recursion depth exceeded" error with the default and - // small recursion limits. - type Child = (X::Child, X::Child); -} - -impl S for Box { - type Child = X; -} - -type Data = Box<(A, A)>; -struct A {} -impl S for A { - // Manually expanding the `Data::Child` here fixes the bug both for a small - // recursion limit, and for the default recursion limit, i.e. the compiler - // gives a "recursion depth exceeded" error message in both cases. This is - // in contrast to the version above in my report, where expanding the - // `Data::Child` type fixes the bug for the small recursion limit, but the - // compiler still hangs for the default recursion limit. - // - //type Child = (A, A); - type Child = ::Child; -} - -fn uhoh() { - uhoh::(); -} - -fn main() { - uhoh::(); -} From c82b6966ff57bda8613b0a370b11ba5673e3ddda Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 8 Oct 2025 12:03:30 -0500 Subject: [PATCH 29/58] better styles --- packages/playground/playground/assets/dxp.css | 192 +----------------- .../playground/src/components/panes.rs | 14 ++ .../playground/server/template/Cargo.lock | 4 +- .../playground/server/template/Cargo.toml | 4 +- .../playground/server/template/Dioxus.toml | 4 +- .../playground/server/template/src/main.rs | 14 +- 6 files changed, 42 insertions(+), 190 deletions(-) diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index 5a1e10f44d..5b02135f5c 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -5,12 +5,15 @@ /* Header */ #dxp-header { - border-bottom: 1px solid var(--dxp-border-light); background-color: var(--dxp-bg-light-darker); height: 36px; display: flex; flex-direction: row; - margin: 0.5rem; + padding: 0.5rem; + border-style: solid; + border-width: 0 0 1px 0; + border-color: var(--light, var(--primary-color-6)) + var(--dark, var(--primary-color-7)); } #dxp-header-left { @@ -105,10 +108,14 @@ } #dxp-panes-draggable { - width: 3px; + width: 12px; background-color: var(--dxp-border-light); cursor: col-resize; user-select: none; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; } #dxp-panes-right { @@ -345,182 +352,3 @@ Liberation Mono, monospace; } - -/* Media Queries */ -/* TODO: Fix right pane responsive design */ -/* @media screen and (max-width: 1000px) { - #dxp-header-right { - width: auto; - margin-left: auto; - } - - #dxp-header-left { - width: auto; - } - - #dxp-panes { - flex-direction: column; - height: auto; - } - - #dxp-panes-left { - width: 100%; - } - - #dxp-panes-draggable { - visibility: hidden; - display: none; - } - - #dxp-panes-right { - width: 100%; - min-height: 400px; - } -} */ - -/* Color Scheme Queries */ - -/* @media screen and (max-width: 1000px) and (prefers-color-scheme: dark) { - #dxp-panes-right { - border-top: 1px solid var(--dxp-border-dark); - } -} */ - -@media screen and (prefers-color-scheme: dark) { - #dxp-playground-root { - border-color: var(--dxp-border-dark); - } - - /* Header */ - #dxp-header { - border-bottom-color: var(--dxp-border-dark); - background-color: var(--dxp-bg-dark-darker); - } - - .dxp-ctrl-btn { - color: var(--dxp-text-dark); - } - - #dxp-menu-btn { - background-color: var(--dxp-bg-dark-lighter); - } - - #dxp-menu-btn:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - #dxp-menu-btn.dxp-open { - border: 1px solid var(--dxp-border-dark-lighter); - } - - #dxp-menu-btn > svg { - color: var(--dxp-text-dark); - } - - #dxp-run-btn { - color: var(--dxp-text-dark); - background-color: var(--dxp-bg-dark-lighter); - } - - #dxp-run-btn > svg { - color: var(--dxp-text-dark); - } - - .dxp-ctrl-btn:hover { - cursor: pointer; - background-color: var(--dxp-bg-dark-lighter-alt); - } - - .dxp-file-btn { - background-color: var(--dxp-bg-dark-lighter); - } - - .dxp-selected-file { - border-color: var(--dxp-border-dark-lighter); - } - - /* Examples */ - #dxp-examples-list { - background-color: var(--dxp-bg-dark-darker); - } - - .dxp-example-project { - color: var(--dxp-text-dark); - border-bottom: 1px solid var(--dxp-bg-dark-lighter-alt); - } - - .dxp-example-project:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - /* Panes */ - - #dxp-panes { - border-left-color: var(--dxp-border-dark); - } - - #dxp-panes-left { - background-color: var(--dxp-bg-dark); - } - - #dxp-panes-draggable { - background-color: var(--dxp-border-dark); - } - - #dxp-panes-right { - background-color: var(--dxp-bg-dark-darker); - } - - #dxp-panes-right > p, - #dxp-panes-right > #dxp-progress-container > p { - color: var(--dxp-text-dark); - } - - #dxp-panes-right > #dxp-progress-container > #dxp-progress { - background-color: var(--dxp-bg-dark-lighter); - } - - /* Modal */ - - #dxp-modal { - background-color: var(--dxp-bg-dark); - border: 1px solid var(--dxp-border-dark); - color: var(--dxp-text-dark); - } - - #dxp-modal-ok-btn { - background-color: var(--dxp-bg-dark-lighter); - color: var(--dxp-text-dark); - } - - #dxp-modal-ok-btn:hover { - background-color: var(--dxp-bg-dark-lighter-alt); - } - - /* Logs */ - - #logs .log { - color: var(--dxp-text-dark); - } - - #logs .log:hover { - background-color: var(--dxp-bg-dark); - } - - #logs .log .level-error { - color: var(--dxp-log-error-dark); - } - - #logs .log .level-warn { - color: var(--dxp-log-warn-dark); - } - - #logs .log .level-info { - color: var(--dxp-log-info-dark); - } - - #logs .log .log-codeblock { - background-color: var(--dxp-bg-dark); - border-color: var(--dxp-border-dark); - } -} diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index 7a0f9b4800..62ae57e16d 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -114,6 +114,20 @@ pub fn Panes( id: "dxp-panes-draggable", onmousedown: draggable_mousedown, onmouseup: stop_dragging, + // Two vertical lines to indicate draggable + svg { + width: "12", + height: "48", + xmlns: "http://www.w3.org/2000/svg", + view_box: "0 0 34 48", + fill: "none", + stroke: "currentColor", + stroke_width: "6", + stroke_linecap: "round", + stroke_linejoin: "round", + path { d: "M10 8v48" } + path { d: "M24 8v48" } + } } // Right Pane div { diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 243730b1c1..7da36e067f 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -824,7 +824,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#b46aa465ae683004e21326f1fe80df812b188613" +source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" dependencies = [ "dioxus", "dioxus-time", @@ -1967,7 +1967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-e05e67a4-8c15-35c2-bfba-94314ad0190e" +name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" version = "0.1.0" dependencies = [ "dioxus", diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index 643dc50289..e499823697 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -2,13 +2,13 @@ [workspace] [package] -name = "play-e05e67a4-8c15-35c2-bfba-94314ad0190e" +name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" version = "0.1.0" edition = "2024" [dependencies] dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } +dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml index 1a6e59527a..a14c80d2de 100644 --- a/packages/playground/server/template/Dioxus.toml +++ b/packages/playground/server/template/Dioxus.toml @@ -1,12 +1,12 @@ [application] -name = "e05e67a4-8c15-35c2-bfba-94314ad0190e" +name = "57d2f289-ba45-3195-ae0a-ea089d2f9bf8" default_platform = "web" out_dir = "dist" asset_dir = "assets" hot_reload = false [web.app] -base_path = "built/e05e67a4-8c15-35c2-bfba-94314ad0190e" +base_path = "built/57d2f289-ba45-3195-ae0a-ea089d2f9bf8" title = "Dioxus Playground" [web.watcher] diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 538ea6c016..6e0f188624 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -1,4 +1,5 @@ -//! The simplest Dioxus app +//! A basic counter example demonstrating signals, +//! event handlers, and basic rendering. use dioxus::prelude::*; @@ -8,7 +9,16 @@ fn main() { #[component] fn App() -> Element { + let mut count = use_signal(|| 0); + rsx! { - div { "Build what is this stuff!" } + p { "Count: {count}" } + div { style: "display: flex;", + button { onclick: move |_| count -= 1, "-" } + button { onclick: move |_| count -= 2, "-" } + button { onclick: move |_| count -= 3, "-" } + button { onclick: move |_| count += 1, "+" } + button { onclick: move |_| count.set(0), "reset" } + } } } From 8e5c0a16b94fe91603c25475adc12a3ce9722094 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 8 Oct 2025 12:51:10 -0500 Subject: [PATCH 30/58] bump dioxus --- Cargo.lock | 342 +++++++----------- Cargo.toml | 1 + docs-src/0.6/src/essentials/async/index.md | 6 - .../0.7/src/essentials/advanced/suspense.md | 14 - .../src/essentials/basics/error_handling.md | 6 - .../src/doc_examples/asynchronous.rs | 108 ------ .../src/doc_examples/data_fetching.rs | 18 +- .../src/doc_examples/error_handling.rs | 44 --- packages/docsite/src/components/playground.rs | 14 +- packages/docsite/src/docs.rs | 16 +- packages/docsite/src/main.rs | 10 +- 11 files changed, 167 insertions(+), 412 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index df5d1a5be5..9f6bfcb3b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1001,8 +1001,8 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize-macro", "serde", @@ -1010,8 +1010,8 @@ dependencies = [ [[package]] name = "const-serialize-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "quote", @@ -1413,28 +1413,28 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", "dioxus-config-macro", "dioxus-config-macros", "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-macro", "dioxus-devtools", "dioxus-document", "dioxus-fullstack", "dioxus-fullstack-macro", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html", - "dioxus-liveview 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-liveview 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-logger", - "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-router", "dioxus-server", "dioxus-signals", - "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-ssr 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-stores", "dioxus-web", "manganis", @@ -1445,8 +1445,8 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "http", @@ -1466,9 +1466,9 @@ dependencies = [ [[package]] name = "dioxus-autofmt" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e26d7984c2730639f0d83dcf727b66ec01acb9954fa8b62b9ee11138b033da88" +checksum = "92bd52f33ff5f4d9cb80b4b2f72cb4bb7220d81bb4be4d6499c63abfb4ab7e37" dependencies = [ "dioxus-rsx", "prettyplease", @@ -1481,8 +1481,8 @@ dependencies = [ [[package]] name = "dioxus-autofmt" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-rsx", "prettyplease", @@ -1495,16 +1495,16 @@ dependencies = [ [[package]] name = "dioxus-cli-config" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "quote", @@ -1512,13 +1512,13 @@ dependencies = [ [[package]] name = "dioxus-config-macros" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "dioxus-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "anyhow", "const_format", @@ -1539,21 +1539,8 @@ dependencies = [ [[package]] name = "dioxus-core-macro" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9280f81c8d58863b3077f1b7ca097e2f2b28d30a5aa02a656fbf72b0aee1bd9f" -dependencies = [ - "convert_case 0.8.0", - "dioxus-rsx", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "dioxus-core-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", @@ -1564,13 +1551,13 @@ dependencies = [ [[package]] name = "dioxus-core-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "dioxus-desktop" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "async-trait", "base64 0.22.1", @@ -1582,8 +1569,8 @@ dependencies = [ "dioxus-core", "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html", "dioxus-interpreter-js", "dioxus-signals", @@ -1594,7 +1581,7 @@ dependencies = [ "global-hotkey", "infer", "jni", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "libc", "muda", "ndk", @@ -1623,8 +1610,8 @@ dependencies = [ [[package]] name = "dioxus-devtools" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -1643,8 +1630,8 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "serde", @@ -1736,8 +1723,8 @@ dependencies = [ "dioxus", "dioxus-cli-config", "dioxus-desktop", - "dioxus-liveview 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-ssr 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-liveview 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-ssr 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-web", "form_urlencoded", "futures", @@ -1767,17 +1754,17 @@ dependencies = [ [[package]] name = "dioxus-document" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-macro", "dioxus-core-types", "dioxus-html", "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "serde", "serde_json", "tracing", @@ -1785,8 +1772,8 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "cargo_metadata", "manganis-core", @@ -1797,8 +1784,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "anyhow", "async-stream", @@ -1818,7 +1805,7 @@ dependencies = [ "dioxus-core", "dioxus-fullstack-core", "dioxus-fullstack-macro", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html", "dioxus-signals", "form_urlencoded", @@ -1861,8 +1848,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "anyhow", "axum-core 0.5.5", @@ -1870,8 +1857,8 @@ dependencies = [ "ciborium", "dioxus-core", "dioxus-document", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-signals", "futures-channel", "futures-util", @@ -1886,8 +1873,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const_format", "convert_case 0.8.0", @@ -1899,9 +1886,9 @@ dependencies = [ [[package]] name = "dioxus-history" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e9e34323717a78ea3f8ba5072ff484744a656e8d422932c19937b67f45113e" +checksum = "a07f1cb988bfae15dc66564616adc98a89fdfbb5e5e94ac28f8a2f2590886ded" dependencies = [ "dioxus-core", "tracing", @@ -1909,8 +1896,8 @@ dependencies = [ [[package]] name = "dioxus-history" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "tracing", @@ -1918,25 +1905,8 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab776b9a156765cc7dd7876891c98b9ab06b1f995d33ff169b06ef4f23cfd437" -dependencies = [ - "dioxus-core", - "dioxus-signals", - "futures-channel", - "futures-util", - "generational-box", - "rustversion", - "slab", - "tracing", - "warnings", -] - -[[package]] -name = "dioxus-hooks" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1951,15 +1921,15 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "async-trait", "bytes", "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-macro", "dioxus-core-types", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html-internal-macro", "dioxus-rsx", "enumset", @@ -1968,7 +1938,7 @@ dependencies = [ "futures-util", "generational-box", "keyboard-types", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustversion", "serde", "serde_json", @@ -1978,8 +1948,8 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -1989,14 +1959,14 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-core-types", "dioxus-html", "js-sys", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", @@ -2008,16 +1978,16 @@ dependencies = [ [[package]] name = "dioxus-liveview" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90ea4ac81b0c239f00c70a06d1433135babca3412817d4c21a1a188964e5a7f" +checksum = "a3a125beceef0c208f32076a7d0e71afc11b4d4fb2a24ca02207b46103e69466" dependencies = [ "axum 0.8.6", "dioxus-cli-config", "dioxus-core", "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-history 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-html", "dioxus-interpreter-js", "futures-channel", @@ -2036,15 +2006,15 @@ dependencies = [ [[package]] name = "dioxus-liveview" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "axum 0.8.6", "dioxus-cli-config", "dioxus-core", "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-html", "dioxus-interpreter-js", "futures-channel", @@ -2063,8 +2033,8 @@ dependencies = [ [[package]] name = "dioxus-logger" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "tracing", @@ -2078,7 +2048,7 @@ version = "0.1.0" dependencies = [ "base64 0.22.1", "dioxus", - "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-core", "dioxus-core-types", "dioxus-devtools", @@ -2120,37 +2090,17 @@ dependencies = [ [[package]] name = "dioxus-router" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6260ba0131670716b7410bc6b2eba13cc7677ba133c9678b5508214a7a2a1794" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-history 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-hooks 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html", - "dioxus-router-macro 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-signals", - "percent-encoding", - "rustversion", - "tracing", - "url", -] - -[[package]] -name = "dioxus-router" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" -dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-macro", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html", - "dioxus-router-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-router-macro", "dioxus-signals", "percent-encoding", "rustversion", @@ -2160,23 +2110,8 @@ dependencies = [ [[package]] name = "dioxus-router-macro" -version = "0.7.0-rc.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71f2013d2871815f6e84478198c5f458c735f053703a800a9ac684b98de2cfa" -dependencies = [ - "base16", - "digest", - "proc-macro2", - "quote", - "sha2", - "slab", - "syn 2.0.106", -] - -[[package]] -name = "dioxus-router-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "base16", "digest", @@ -2189,8 +2124,8 @@ dependencies = [ [[package]] name = "dioxus-rsx" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -2200,9 +2135,9 @@ dependencies = [ [[package]] name = "dioxus-rsx-hotreload" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c796e02557a4de1f4b4850e554b802b7bcce607103e0b1d5b4c530268791005e" +checksum = "46c5d348d18411c1e1a78b9f7d64c36495d63597687d5a398e82e2d887ccf00a" dependencies = [ "dioxus-core", "dioxus-core-types", @@ -2217,11 +2152,11 @@ dependencies = [ [[package]] name = "dioxus-rsx-rosetta" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case 0.8.0", - "dioxus-autofmt 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-autofmt 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-html", "dioxus-rsx", "html_parser", @@ -2246,7 +2181,7 @@ name = "dioxus-search" version = "0.1.0" dependencies = [ "bytes", - "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-router", "dioxus-search-macro", "dioxus-search-shared", "getrandom 0.2.16", @@ -2272,7 +2207,7 @@ name = "dioxus-search-shared" version = "0.1.0" dependencies = [ "bytes", - "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-router", "getrandom 0.2.16", "log", "scraper", @@ -2286,8 +2221,8 @@ dependencies = [ [[package]] name = "dioxus-server" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "anyhow", "async-trait", @@ -2299,18 +2234,18 @@ dependencies = [ "dashmap", "dioxus-cli-config", "dioxus-core", - "dioxus-core-macro 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-core-macro", "dioxus-devtools", "dioxus-document", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", - "dioxus-hooks 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-hooks", "dioxus-html", "dioxus-interpreter-js", "dioxus-logger", - "dioxus-router 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-router", "dioxus-signals", - "dioxus-ssr 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-ssr 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "enumset", "futures", "futures-channel", @@ -2343,8 +2278,8 @@ dependencies = [ [[package]] name = "dioxus-signals" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "futures-channel", @@ -2358,9 +2293,9 @@ dependencies = [ [[package]] name = "dioxus-ssr" -version = "0.7.0-rc.0" +version = "0.7.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21c377da1f2ea708be1112dd61189d6dcd19c8db25208b750c3849f760fa854d" +checksum = "ae8d580119df51b292f91f77085a0adc5eca99347c483ad3e3893c827a179913" dependencies = [ "askama_escape 0.13.0", "dioxus-core", @@ -2370,8 +2305,8 @@ dependencies = [ [[package]] name = "dioxus-ssr" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "askama_escape 0.13.0", "dioxus-core", @@ -2381,8 +2316,8 @@ dependencies = [ [[package]] name = "dioxus-stores" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2391,8 +2326,8 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2433,8 +2368,8 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2442,7 +2377,7 @@ dependencies = [ "dioxus-devtools", "dioxus-document", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.0 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", "dioxus-html", "dioxus-interpreter-js", "dioxus-signals", @@ -2451,7 +2386,7 @@ dependencies = [ "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle 0.7.0-rc.0", + "lazy-js-bundle 0.7.0-rc.1", "rustc-hash 2.1.1", "send_wrapper", "serde", @@ -3204,8 +3139,8 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "parking_lot", "tracing", @@ -4328,8 +4263,8 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" [[package]] name = "lazy_static" @@ -4561,8 +4496,8 @@ dependencies = [ [[package]] name = "manganis" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize", "manganis-core", @@ -4571,8 +4506,8 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -4582,8 +4517,8 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "dunce", "macro-string", @@ -4685,7 +4620,7 @@ version = "0.0.0" dependencies = [ "anyhow", "convert_case 0.6.0", - "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", "dioxus-rsx", "macro_state", "mdbook-shared", @@ -4708,7 +4643,7 @@ name = "mdbook-gen-example" version = "0.0.0" dependencies = [ "dioxus", - "dioxus-autofmt 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", "mdbook-gen", "mdbook-shared", "prettyplease", @@ -6341,6 +6276,7 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "native-tls", "percent-encoding", "pin-project-lite", @@ -7151,8 +7087,8 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "js-sys", "libc", @@ -7169,8 +7105,8 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.0-rc.0" -source = "git+https://github.com/dioxuslabs/dioxus#0b1f2fc8c24a74cca3f3b7501df2b5a3048d529f" +version = "0.7.0-rc.1" +source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" dependencies = [ "serde", ] @@ -8142,7 +8078,7 @@ name = "use-mdbook" version = "0.1.0" dependencies = [ "dioxus", - "dioxus-router 0.7.0-rc.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-router", "lazy_static", "mdbook-macro", "mdbook-shared", @@ -8520,9 +8456,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] diff --git a/Cargo.toml b/Cargo.toml index a7e2ac8653..eae18262f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -133,6 +133,7 @@ dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } dioxus = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } +dioxus-router = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-core-types = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/docs-src/0.6/src/essentials/async/index.md b/docs-src/0.6/src/essentials/async/index.md index 6bf9c23707..aaeae8246c 100644 --- a/docs-src/0.6/src/essentials/async/index.md +++ b/docs-src/0.6/src/essentials/async/index.md @@ -106,12 +106,6 @@ If you need to change the loading view while a specific task is loading, you can {{#include ../docs-router/src/doc_examples/untested_06/asynchronous.rs:suspense_boundary_with_loading_placeholder}} ``` -```inject-dioxus -DemoFrame { - asynchronous::DogGridViewWithLoadingPlaceholder {} -} -``` - ## Suspense with Fullstack To use suspense in your fullstack application, you need to use the `use_server_future` hook instead of `use_resource`. `use_server_future` handles serialization of the result of the future for hydration. It will also suspend automatically, so you don't need to call `.suspend()` on the future. diff --git a/docs-src/0.7/src/essentials/advanced/suspense.md b/docs-src/0.7/src/essentials/advanced/suspense.md index 022e2ba518..75e91c790d 100644 --- a/docs-src/0.7/src/essentials/advanced/suspense.md +++ b/docs-src/0.7/src/essentials/advanced/suspense.md @@ -16,20 +16,6 @@ DemoFrame { } ``` -## Customizing the loading view from children - -If you need to change the loading view while a specific task is loading, you can provide a different loading view with the `with_loading_placeholder` method. The loading placeholder you return from the method will be passed to the suspense boundary and may choose to render it instead of the default loading view: - -```rust -{{#include ../docs-router/src/doc_examples/asynchronous.rs:suspense_boundary_with_loading_placeholder}} -``` - -```inject-dioxus -DemoFrame { - asynchronous::DogGridViewWithLoadingPlaceholder {} -} -``` - ## Suspense with Fullstack Dioxus fullstack will wait for suspended futures during server-side rendering. This means your async data loading starts sooner and search engines can see the resolved version of your page. However, using suspense in fullstack does require some changes for hydration compatibility. diff --git a/docs-src/0.7/src/essentials/basics/error_handling.md b/docs-src/0.7/src/essentials/basics/error_handling.md index 5806eb76c6..0940884dbb 100644 --- a/docs-src/0.7/src/essentials/basics/error_handling.md +++ b/docs-src/0.7/src/essentials/basics/error_handling.md @@ -62,12 +62,6 @@ You can add additional context to your errors with the [`Context`](https://docs. {{#include ../docs-router/src/doc_examples/error_handling.rs:add_context}} ``` -If you need some custom UI for the error message, you can call `show` on a result to attach an Element to the error variant. The parent error boundary can choose to render this element instead of the default error message: - -```rust, no_run -{{#include ../docs-router/src/doc_examples/error_handling.rs:show}} -``` - ## Downcasting Specific Errors When handling errors in Error Boundaries, we can match on specific types of errors, optionally choosing to capture the error and prevent it from bubbling. diff --git a/packages/docs-router/src/doc_examples/asynchronous.rs b/packages/docs-router/src/doc_examples/asynchronous.rs index 94608163ae..c1737d2f9c 100644 --- a/packages/docs-router/src/doc_examples/asynchronous.rs +++ b/packages/docs-router/src/doc_examples/asynchronous.rs @@ -470,114 +470,6 @@ mod suspense_boundary { // ANCHOR_END: suspense_boundary } -pub use suspense_boundary_with_loading_placeholder::DogGridViewWithLoadingPlaceholder; - -mod suspense_boundary_with_loading_placeholder { - use super::{BreedResponse, ClientOnly}; - use dioxus::prelude::*; - - pub fn DogGridViewWithLoadingPlaceholder() -> Element { - let mut uuid = use_signal(|| 0); - rsx! { - div { - height: "20em", - ClientOnly { - button { onclick: move |_| uuid += 1, "🔄" } - {std::iter::once(rsx! { - DogGrid { key: "{uuid}" } - })} - } - } - } - } - - // ANCHOR: suspense_boundary_with_loading_placeholder - fn DogGrid() -> Element { - rsx! { - SuspenseBoundary { - // The fallback closure accepts a SuspenseContext which contains - // information about the suspended component - fallback: |suspense_context: SuspenseContext| if let Some(view) = suspense_context.suspense_placeholder() { - view - } else { - rsx! { - div { - width: "100%", - height: "100%", - display: "flex", - align_items: "center", - justify_content: "center", - "Loading..." - } - } - }, - div { - display: "flex", - flex_direction: "column", - BreedGallery { - breed: "hound" - } - BreedGallery { - breed: "poodle" - } - BreedGallery { - breed: "beagle" - } - } - } - } - } - - #[component] - fn BreedGallery(breed: ReadOnlySignal) -> Element { - let response = use_resource(move || async move { - gloo_timers::future::TimeoutFuture::new(breed().len() as u32 * 100).await; - reqwest::Client::new() - .get(format!("https://dog.ceo/api/breed/{breed}/images")) - .send() - .await? - .json::() - .await - }) - .suspend() - // You can pass up a loading placeholder to the nearest SuspenseBoundary - // with the with_loading_placeholder method - .with_loading_placeholder(move || { - rsx! { - div { - width: "100%", - height: "100%", - display: "flex", - align_items: "center", - justify_content: "center", - "Loading {breed}..." - } - } - })?; - - // Then you can just handle the happy path with the resolved future - rsx! { - div { - display: "flex", - flex_direction: "row", - match &*response.read() { - Ok(urls) => rsx! { - for image in urls.iter().take(3) { - img { - src: "{image}", - width: "100px", - height: "100px", - } - } - }, - Err(err) => rsx! { "Failed to fetch response: {err}" }, - } - } - } - } - // ANCHOR_END: suspense_boundary_with_loading_placeholder -} - #[cfg(not(feature = "fullstack"))] pub use suspense_boundary::DogGridView as DogGridFullstack; #[cfg(feature = "fullstack")] diff --git a/packages/docs-router/src/doc_examples/data_fetching.rs b/packages/docs-router/src/doc_examples/data_fetching.rs index 11cae522e8..0f0e115bdd 100644 --- a/packages/docs-router/src/doc_examples/data_fetching.rs +++ b/packages/docs-router/src/doc_examples/data_fetching.rs @@ -23,7 +23,8 @@ mod waterfall_effect { fn DogView() -> Element { let poodle_img = use_resource(|| fetch_dog_image("poodle")); - let poodle_img = match poodle_img() { + let read = poodle_img.read(); + let poodle_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { @@ -34,7 +35,8 @@ mod waterfall_effect { let golden_retriever_img = use_resource(|| fetch_dog_image("golden retriever")); - let golden_retriever_img = match golden_retriever_img() { + let read = golden_retriever_img.read(); + let golden_retriever_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { @@ -45,7 +47,8 @@ mod waterfall_effect { let pug_img = use_resource(|| fetch_dog_image("pug")); - let pug_img = match pug_img() { + let read = pug_img.read(); + let pug_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { @@ -93,7 +96,8 @@ mod no_waterfall_effect { let golden_retriever_img = use_resource(|| fetch_dog_image("golden retriever")); let pug_img = use_resource(|| fetch_dog_image("pug")); - let poodle_img = match poodle_img() { + let read = poodle_img.read(); + let poodle_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { @@ -101,7 +105,8 @@ mod no_waterfall_effect { }; } }; - let golden_retriever_img = match golden_retriever_img() { + let read = golden_retriever_img.read(); + let golden_retriever_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { @@ -109,7 +114,8 @@ mod no_waterfall_effect { }; } }; - let pug_img = match pug_img() { + let read = pug_img.read(); + let pug_img = match read.as_ref() { Some(Ok(src)) => src, _ => { return rsx! { diff --git a/packages/docs-router/src/doc_examples/error_handling.rs b/packages/docs-router/src/doc_examples/error_handling.rs index 6cf03598f5..fedc99fb42 100644 --- a/packages/docs-router/src/doc_examples/error_handling.rs +++ b/packages/docs-router/src/doc_examples/error_handling.rs @@ -76,50 +76,6 @@ mod add_context { // ANCHOR_END: add_context } -mod show { - use super::*; - // ANCHOR: show - #[component] - fn Parent() -> Element { - rsx! { - ErrorBoundary { - // The error boundary accepts a closure that will be rendered when an error is thrown in any - // of the children - handle_error: |error: ErrorContext| { - if let Some(error_ui) = error.show() { - rsx! { - {error_ui} - } - } else { - rsx! { - div { - "Oops, we encountered an error. Please report this to the developer of this application" - } - } - } - }, - ThrowsError {} - } - } - } - // ANCHOR_END: show - - #[component] - fn ThrowsError() -> Element { - let number: i32 = use_hook(|| "1...234").parse().show(|error| { - rsx! { - div { - background_color: "red", - color: "white", - "Error parsing number: {error}" - } - } - })?; - - todo!() - } -} - pub use phone_number_validation::PhoneNumberValidation; mod phone_number_validation { diff --git a/packages/docsite/src/components/playground.rs b/packages/docsite/src/components/playground.rs index 0881950fd2..ac2fdbfe14 100644 --- a/packages/docsite/src/components/playground.rs +++ b/packages/docsite/src/components/playground.rs @@ -25,7 +25,7 @@ pub fn Playground(share_code: Option) -> Element { rsx! { ErrorBoundary { handle_error: move |err: ErrorContext| { - let errors = err.errors(); + let error = err.error().unwrap(); rsx! { div { class: "mx-auto mt-8 max-w-3/4", @@ -35,10 +35,7 @@ pub fn Playground(share_code: Option) -> Element { br {} - for error in errors { - p { class: "dark:text-white font-light text-ghdarkmetal", "{error:?}" } - br {} - } + p { class: "dark:text-white font-light text-ghdarkmetal", "{error:?}" } } } }, @@ -53,10 +50,3 @@ pub fn Playground(share_code: Option) -> Element { rsx! {} } } - -#[component] -pub fn SharePlayground(share_code: String) -> Element { - rsx! { - Playground { share_code } - } -} diff --git a/packages/docsite/src/docs.rs b/packages/docsite/src/docs.rs index 0ced0a8b67..e13cdd8bd8 100644 --- a/packages/docsite/src/docs.rs +++ b/packages/docsite/src/docs.rs @@ -39,13 +39,15 @@ pub fn use_try_current_docs_version() -> Option { Route::Docs05 { child } => Some(CurrentDocsVersion::V05(child)), Route::Docs04 { child } => Some(CurrentDocsVersion::V04(child)), Route::Docs03 { child } => Some(CurrentDocsVersion::V03(child)), - Route::Homepage {} => None, - Route::Components { .. } => None, - Route::Awesome {} => None, - Route::Deploy {} => None, - Route::BlogList {} => None, - Route::BlogPost { .. } => None, - Route::Err404 { .. } => None, + Route::Homepage {} + | Route::Components { .. } + | Route::Awesome {} + | Route::Deploy {} + | Route::BlogList {} + | Route::BlogPost { .. } + | Route::Playground { .. } + | Route::SharePlayground { .. } + | Route::Err404 { .. } => None, } } diff --git a/packages/docsite/src/main.rs b/packages/docsite/src/main.rs index 14a040ce9e..d7752e663d 100644 --- a/packages/docsite/src/main.rs +++ b/packages/docsite/src/main.rs @@ -202,13 +202,11 @@ pub enum Route { #[route("/")] Homepage {}, - // #[route("/playground")] - // Playground {}, - - // #[route("/playground/shared/:share_code")] - // SharePlayground { share_code: String }, - + #[route("/playground")] + Playground {}, + #[route("/playground/shared/:share_code", Playground)] + SharePlayground { share_code: String }, #[route("/awesome")] Awesome {}, From a3b8f7b01838a8bbfc551153c81ea3b8c94e563f Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 9 Oct 2025 12:37:06 -0500 Subject: [PATCH 31/58] clean up UI --- packages/docsite/assets/main.css | 267 +++++++++--------- packages/docsite/src/components/nav.rs | 2 +- packages/docsite/src/components/playground.rs | 6 +- packages/playground/playground/assets/dxp.css | 28 +- .../playground/src/components/header.rs | 6 +- .../src/dx_components/button/component.rs | 3 +- .../playground/server/src/build/builder.rs | 6 +- packages/playground/server/src/main.rs | 14 +- .../playground/server/template/Cargo.lock | 2 +- .../playground/server/template/Cargo.toml | 2 +- .../playground/server/template/Dioxus.toml | 4 +- .../server/template/snippets/Cargo.toml | 2 +- .../playground/server/template/src/main.rs | 5 +- 13 files changed, 166 insertions(+), 181 deletions(-) diff --git a/packages/docsite/assets/main.css b/packages/docsite/assets/main.css index 589075f38a..555658543e 100644 --- a/packages/docsite/assets/main.css +++ b/packages/docsite/assets/main.css @@ -1,52 +1,49 @@ @media (min-width: 767px) { - .styled-scrollbar { - scrollbar-width: thin; - scrollbar-color: #21252900 transparent; - scrollbar-gutter: stable; - overflow: auto; - } - - .styled-scrollbar::-webkit-scrollbar { - height: 0.5rem; - width: 0.375rem; - } - - .styled-scrollbar::-webkit-scrollbar-track { - background-color: transparent; - } - - .styled-scrollbar::-webkit-scrollbar-thumb { - border-radius: 0.375rem; - border: 3px solid transparent; - background-clip: content-box; - scrollbar-width: thin; - scrollbar-color: #0080ff #fff; - } - - /* safari bug, the thumb doesn't change unless we trigger a hover event on the item itself */ - .styled-scrollbar:hover { - min-height: 1px; - scrollbar-color: #212529 transparent; - } - - .styled-scrollbar:hover::-webkit-scrollbar-thumb { - border-radius: 0.375rem; - border: 3px solid transparent; - background-clip: content-box; - scrollbar-width: thin; - scrollbar-color: #0080ff #fff; - background: #d0d3d7; - } + .styled-scrollbar { + scrollbar-width: thin; + scrollbar-color: #21252900 transparent; + scrollbar-gutter: stable; + overflow: auto; + } + + .styled-scrollbar::-webkit-scrollbar { + height: 0.5rem; + width: 0.375rem; + } + + .styled-scrollbar::-webkit-scrollbar-track { + background-color: transparent; + } + + .styled-scrollbar::-webkit-scrollbar-thumb { + border-radius: 0.375rem; + border: 3px solid transparent; + background-clip: content-box; + scrollbar-width: thin; + scrollbar-color: #0080ff #fff; + } + + /* safari bug, the thumb doesn't change unless we trigger a hover event on the item itself */ + .styled-scrollbar:hover { + min-height: 1px; + scrollbar-color: #212529 transparent; + } + + .styled-scrollbar:hover::-webkit-scrollbar-thumb { + border-radius: 0.375rem; + border: 3px solid transparent; + background-clip: content-box; + scrollbar-width: thin; + scrollbar-color: #0080ff #fff; + background: #d0d3d7; + } } .playground-container { - height: 900px; - display: flex; - flex-direction: column; - /* width: 100vw; - height: 80vh; - display: flex; - flex-direction: column; */ + width: 100vw; + height: 80vh; + display: flex; + flex-direction: column; } /* .full-chapter { @@ -66,39 +63,39 @@ } */ html { - &:where([data-theme="dark"], [data-theme="dark"] *) { - background-color: black; - } + &:where([data-theme="dark"], [data-theme="dark"] *) { + background-color: black; + } } .markdown-body > div + p { - margin-top: 2rem; + margin-top: 2rem; } -.markdown-body > video, .markdown-body > img { - margin-bottom: 2rem; +.markdown-body > video, +.markdown-body > img { + margin-bottom: 2rem; } - .codeblock { - font-weight: 400; + font-weight: 400; } .codeblock > pre { - &:where([data-theme="light"], [data-theme="light"] *) { - background-color: rgb(37, 36, 36) !important; - } + &:where([data-theme="light"], [data-theme="light"] *) { + background-color: rgb(37, 36, 36) !important; + } } .codeblock > pre { - border-radius: 0px 0px 0px 0px; - margin-bottom: 0px !important; + border-radius: 0px 0px 0px 0px; + margin-bottom: 0px !important; } .markdown-body { - box-sizing: border-box; - min-width: 200px; - list-style: disc; + box-sizing: border-box; + min-width: 200px; + list-style: disc; } /* @@ -106,18 +103,18 @@ https: //stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjus This way clicking on headers snaps to the height of the navbar + some padding */ :target { - scroll-margin-top: calc(4rem + 8px); + scroll-margin-top: calc(4rem + 8px); } @media (max-width: 767px) { - .markdown-body { - /* padding: 15px; */ - } + .markdown-body { + /* padding: 15px; */ + } } .main-side-nav { - max-height: calc(100vh - 4rem); - overflow: auto; + max-height: calc(100vh - 4rem); + overflow: auto; } /* on small screens we want to hide the copy div @@ -125,139 +122,141 @@ we have to select it based on the content since the styling is buried deep in md It's so unliklely anyone is copying text on mobile that we can just hide it */ @media (max-width: 767px) { - .markdown-body - button[onclick="navigator.clipboard.writeText(this.previousElementSibling.innerText)"] { - display: none; - } + .markdown-body + button[onclick="navigator.clipboard.writeText(this.previousElementSibling.innerText)"] { + display: none; + } } .dioxus-demo input { - border: 1px solid #ced4da; - border-radius: 5px; - background-color: white; - padding: 5px; - margin: 5px; - max-width: 150px; + border: 1px solid #ced4da; + border-radius: 5px; + background-color: white; + padding: 5px; + margin: 5px; + max-width: 150px; } .dioxus-demo { - border-width: 1px; - border-color: #ced4da; + border-width: 1px; + border-color: #ced4da; - /* text-align: center; */ + /* text-align: center; */ } .dioxus-demo h1 { - margin-top: 16px; + margin-top: 16px; } .dioxus-show { - z-index: 10000; - visibility: visible; - transition: opacity 0.1s, scale 0.1s; - opacity: 1; - scale: 1; + z-index: 10000; + visibility: visible; + transition: + opacity 0.1s, + scale 0.1s; + opacity: 1; + scale: 1; } .dioxus-hide { - z-index: -1; - visibility: hidden; - opacity: 0; - scale: 1.1; + z-index: -1; + visibility: hidden; + opacity: 0; + scale: 1.1; } .markdown-body ul { - list-style: disc; + list-style: disc; } .markdown-body img { - max-height: 600px; + max-height: 600px; } .markdown-body video { - max-height: 600px; + max-height: 600px; } .markdown-body li { - display: list-item; + display: list-item; } .markdown-body ol { - list-style: decimal; + list-style: decimal; } .dioxus-blog-post img, .centered-overflow { - max-height: 700px; - max-width: 100%; - /* max-width: min(1200px, 95vw); */ - width: auto; - margin-left: 50%; - transform: translateX(-50%); - margin-bottom: 1rem; - border-radius: 6px; + max-height: 700px; + max-width: 100%; + /* max-width: min(1200px, 95vw); */ + width: auto; + margin-left: 50%; + transform: translateX(-50%); + margin-bottom: 1rem; + border-radius: 6px; } .dioxus-blog-post h2 { - margin-top: 2.5rem; - padding-top: 2.5rem; - padding-bottom: 0.25em; + margin-top: 2.5rem; + padding-top: 2.5rem; + padding-bottom: 0.25em; } .highlight pre, .markdown-body pre { - background-color: #1e1e1e; + background-color: #1e1e1e; } .dioxus-blog-post h1 { - /* text-align: center; */ + /* text-align: center; */ } .dioxus-blog-post - :where(h2:not(:is(h1 + h2))):not( - :where([class~="not-prose"], [class~="not-prose"] *) - ) { - border-top-style: solid; - border-top-width: 1px; - border-color: #e5e7eb; + :where(h2:not(:is(h1 + h2))):not( + :where([class~="not-prose"], [class~="not-prose"] *) + ) { + border-top-style: solid; + border-top-width: 1px; + border-color: #e5e7eb; } .navbar_externalArrow___VWBd { - position: absolute; - top: 4px; - right: 0px; + position: absolute; + top: 4px; + right: 0px; } .markdown-body ul { - list-style: disc; + list-style: disc; } .markdown-body ol { - list-style: decimal; + list-style: decimal; } .markdown-body li { - display: list-item; + display: list-item; } .markdown-body > div > button { - display: inline-block; - background-color: rgba(209, 213, 219, 0.3); - border-radius: 0.25rem; - padding: 0.25rem 0.5rem; - border: 1px solid #ced4da; - margin: 0.25rem; + display: inline-block; + background-color: rgba(209, 213, 219, 0.3); + border-radius: 0.25rem; + padding: 0.25rem 0.5rem; + border: 1px solid #ced4da; + margin: 0.25rem; } .markdown-body .header { - color: inherit; + color: inherit; } .textured-body { - background-repeat: repeat; - background-image: url("data:image/png;base64,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"); + background-repeat: repeat; + background-image: url("data:image/png;base64,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"); } @media (prefers-color-scheme: dark) { - .textured-body { - color: #e2e5e9; - background-repeat: repeat; - background-image: url("data:image/png;base64,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"); - } + .textured-body { + color: #e2e5e9; + background-repeat: repeat; + background-image: url("data:image/png;base64,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"); + } } diff --git a/packages/docsite/src/components/nav.rs b/packages/docsite/src/components/nav.rs index 47b9bd027f..ba6ac14686 100644 --- a/packages/docsite/src/components/nav.rs +++ b/packages/docsite/src/components/nav.rs @@ -145,7 +145,7 @@ static LINKS: &[(&str, &str)] = &[ }, ), // ("SDK", "/sdk"), - // ("Playground", "/playground"), + ("Playground", "/playground"), ("Components", "/components"), // ("Awesome", "/awesome"), ("Blog", "/blog"), diff --git a/packages/docsite/src/components/playground.rs b/packages/docsite/src/components/playground.rs index ac2fdbfe14..adc034b9c8 100644 --- a/packages/docsite/src/components/playground.rs +++ b/packages/docsite/src/components/playground.rs @@ -4,8 +4,8 @@ use dioxus_playground::PlaygroundUrls; #[cfg(not(feature = "production"))] const URLS: PlaygroundUrls = PlaygroundUrls { socket: "ws://localhost:3000/ws", - server: "http://localhost:3000/built/", - location: "http://localhost:8080", + server: "http://localhost:3000", + location: "http://localhost:8080/playground", }; #[cfg(feature = "production")] @@ -40,7 +40,7 @@ pub fn Playground(share_code: Option) -> Element { } }, dioxus_playground::Playground { - class: "playground-container max-w-screen-2xl mx-auto mt-8", + class: "playground-container max-w-screen-2xl mx-auto", urls: URLS, share_code, } diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index 5b02135f5c..6458ae3735 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -6,7 +6,6 @@ /* Header */ #dxp-header { background-color: var(--dxp-bg-light-darker); - height: 36px; display: flex; flex-direction: row; padding: 0.5rem; @@ -52,25 +51,16 @@ transition: background-color 0.2s ease; } -#dxp-menu-btn { - background-color: var(--dxp-bg-light-lighter); - display: flex; - align-items: center; - justify-content: center; - padding: 5px; -} - -#dxp-menu-btn:hover { - cursor: pointer; - background-color: var(--dxp-bg-light-lighter-alt); -} - -#dxp-menu-btn.dxp-open { - border: 1px solid var(--dxp-border-light-lighter); +#dxp-header-share-btn { + margin-left: 8px; + width: 8rem; } - -#dxp-menu-btn > svg { - color: var(--dxp-text-light); +@media (max-width: 600px) { + #dxp-header-share-btn { + width: 6rem; + padding-left: 0.25rem; + padding-right: 0.25rem; + } } .dxp-ctrl-btn:hover { diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 8fe3f4eed1..46b9696547 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -35,6 +35,7 @@ pub fn Header( // Examples button/menu Select:: { + width: "75%", value: Some(project()), on_value_change: move |example: Option| { use crate::monaco; @@ -85,6 +86,7 @@ pub fn Header( // Share button Button { variant: ButtonVariant::Secondary, + id: "dxp-header-share-btn", onclick: move |_| async move { share_btn_text.set("Sharing..."); match copy_share_link(&api_client(), project, urls.location).await { @@ -113,8 +115,10 @@ pub fn Header( "data-disabled": build.stage().is_running(), display: "flex", flex_direction: "row", - align_items: "center", + align_items: "between", + justify_content: "center", gap: "0.5rem", + width: "10rem", onclick: move |_| { on_rebuild.call(()); }, diff --git a/packages/playground/playground/src/dx_components/button/component.rs b/packages/playground/playground/src/dx_components/button/component.rs index 6e6a96780b..05221e1c06 100644 --- a/packages/playground/playground/src/dx_components/button/component.rs +++ b/packages/playground/playground/src/dx_components/button/component.rs @@ -29,6 +29,7 @@ pub fn Button( #[props(extends=GlobalAttributes)] #[props(extends=button)] attributes: Vec, + class: Option, onclick: Option>, onmousedown: Option>, onmouseup: Option>, @@ -38,7 +39,7 @@ pub fn Button( document::Link { rel: "stylesheet", href: asset!("./style.css") } button { - class: "button", + class: "button ".to_string() + class.as_deref().unwrap_or_default(), "data-style": variant.class(), onclick: move |event| { if let Some(f) = &onclick { diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 4723fdd49a..aa853acd43 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -232,7 +232,6 @@ async fn dx_patch_build( env: &EnvVars, cache_dir: &Path, ) -> Result, BuildError> { - tracing::info!("patching {:?}", request.previous_build_id); setup_template(&env.build_template_path, &request, true).await?; let mut command = Command::new("dx"); command @@ -275,6 +274,11 @@ async fn dx_patch_build( } } + // Dump logs in debug. + for log in logs { + debug!("{log}"); + } + Err(BuildError::DxFailed(None)) } diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 650b17e4d4..d1eae5436b 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -23,12 +23,6 @@ mod serve; mod share; mod ws; -/// Rate limiter configuration. -/// How many requests each user should get within a time period. -const REQUESTS_PER_INTERVAL: u64 = 60; -/// The period of time after the request limit resets. -const RATE_LIMIT_INTERVAL: Duration = Duration::from_secs(1); - #[tokio::main] async fn main() { #[cfg(feature = "tracing")] @@ -63,8 +57,8 @@ async fn main() { // Allow bursts with up to five requests per IP address // and replenishes one element every 30 seconds let governor_conf = GovernorConfigBuilder::default() - .per_second(60) - .burst_size(120) + .per_second(120) + .burst_size(240) .finish() .unwrap(); @@ -96,10 +90,6 @@ async fn main() { .layer(CorsLayer::very_permissive()) .layer(BufferLayer::new(1024)) .layer(GovernorLayer::new(governor_conf)) - .layer(RateLimitLayer::new( - REQUESTS_PER_INTERVAL, - RATE_LIMIT_INTERVAL, - )) .layer(secure_ip_src.into_extension()) .layer(middleware::from_fn_with_state( state.clone(), diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock index 7da36e067f..7dff1b6e17 100644 --- a/packages/playground/server/template/Cargo.lock +++ b/packages/playground/server/template/Cargo.lock @@ -1967,7 +1967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" version = "0.1.0" dependencies = [ "dioxus", diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml index e499823697..7b08c2e9d4 100644 --- a/packages/playground/server/template/Cargo.toml +++ b/packages/playground/server/template/Cargo.toml @@ -2,7 +2,7 @@ [workspace] [package] -name = "play-57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" version = "0.1.0" edition = "2024" diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml index a14c80d2de..feb660d85c 100644 --- a/packages/playground/server/template/Dioxus.toml +++ b/packages/playground/server/template/Dioxus.toml @@ -1,12 +1,12 @@ [application] -name = "57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +name = "5f1689ca-25e2-3fea-96d4-75ad3e26efa9" default_platform = "web" out_dir = "dist" asset_dir = "assets" hot_reload = false [web.app] -base_path = "built/57d2f289-ba45-3195-ae0a-ea089d2f9bf8" +base_path = "built/5f1689ca-25e2-3fea-96d4-75ad3e26efa9" title = "Dioxus Playground" [web.watcher] diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index e0b08e07b7..c6465e50b3 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -8,7 +8,7 @@ edition = "2024" [dependencies] dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } +dioxus-primitives = { git = "https://github.com/ealmloff/components", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 6e0f188624..5cfde7b728 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -12,13 +12,10 @@ fn App() -> Element { let mut count = use_signal(|| 0); rsx! { - p { "Count: {count}" } + p { "Count: {count*2}" } div { style: "display: flex;", button { onclick: move |_| count -= 1, "-" } - button { onclick: move |_| count -= 2, "-" } - button { onclick: move |_| count -= 3, "-" } button { onclick: move |_| count += 1, "+" } - button { onclick: move |_| count.set(0), "reset" } } } } From c1b4fe14456b6f864c1ee2c765794473f75ee680 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 9 Oct 2025 12:41:54 -0500 Subject: [PATCH 32/58] pin diouxs versions --- packages/playground/server/template/snippets/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index c6465e50b3..b322139256 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -7,8 +7,8 @@ version = "0.1.0" edition = "2024" [dependencies] -dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/ealmloff/components", version = "0.0.1", default-features = false, features = ["router"] } +dioxus = { git = "https://github.com/DioxusLabs/dioxus", rev = "05c0980", features = ["web", "router"] } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", rev = "2901fd2", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" From df69be380ce2de568c900404807cdec97a5ac8a8 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Thu, 9 Oct 2025 12:51:13 -0500 Subject: [PATCH 33/58] remove untracked files --- .../playground/server/template/Cargo.lock | 3539 ----------------- .../playground/server/template/Cargo.toml | 42 - .../playground/server/template/Dioxus.toml | 22 - 3 files changed, 3603 deletions(-) delete mode 100644 packages/playground/server/template/Cargo.lock delete mode 100644 packages/playground/server/template/Cargo.toml delete mode 100644 packages/playground/server/template/Dioxus.toml diff --git a/packages/playground/server/template/Cargo.lock b/packages/playground/server/template/Cargo.lock deleted file mode 100644 index 7dff1b6e17..0000000000 --- a/packages/playground/server/template/Cargo.lock +++ /dev/null @@ -1,3539 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-tungstenite" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee88b4c88ac8c9ea446ad43498955750a4bbe64c4392f21ccfe5d952865e318f" -dependencies = [ - "atomic-waker", - "futures-core", - "futures-io", - "futures-task", - "futures-util", - "log", - "pin-project-lite", - "tungstenite", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "axum" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" -dependencies = [ - "axum-core", - "bytes", - "form_urlencoded", - "futures-util", - "http", - "http-body", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "multer", - "percent-encoding", - "pin-project-lite", - "serde_core", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "sync_wrapper", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link", -] - -[[package]] -name = "base16" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -dependencies = [ - "serde", -] - -[[package]] -name = "cc" -version = "1.2.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" -dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cfb" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" -dependencies = [ - "byteorder", - "fnv", - "uuid", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "charset" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" -dependencies = [ - "base64", - "encoding_rs", -] - -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "const-serialize" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "const-serialize-macro", - "serde", -] - -[[package]] -name = "const-serialize-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "const-str" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4d34b8f066904ed7cfa4a6f9ee96c3214aa998cb44b69ca20bd2054f47402ed" - -[[package]] -name = "const_format" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "content_disposition" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc14a88e1463ddd193906285abe5c360c7e8564e05ccc5d501755f7fbc9ca9c" -dependencies = [ - "charset", -] - -[[package]] -name = "convert_case" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - -[[package]] -name = "cookie_store" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" -dependencies = [ - "cookie", - "document-features", - "idna", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time", - "url", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "darling" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "deranged" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" -dependencies = [ - "derive_more-impl", -] - -[[package]] -name = "derive_more-impl" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dioxus" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-asset-resolver", - "dioxus-cli-config", - "dioxus-config-macro", - "dioxus-config-macros", - "dioxus-core", - "dioxus-core-macro", - "dioxus-devtools", - "dioxus-document", - "dioxus-fullstack", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-logger", - "dioxus-router", - "dioxus-signals", - "dioxus-stores", - "dioxus-web", - "manganis", - "subsecond", - "warnings", -] - -[[package]] -name = "dioxus-asset-resolver" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-cli-config", - "http", - "infer", - "jni", - "js-sys", - "manganis-core", - "ndk", - "ndk-context", - "ndk-sys", - "percent-encoding", - "thiserror 2.0.17", - "tokio", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "dioxus-cli-config" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "dioxus-config-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "dioxus-config-macros" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" - -[[package]] -name = "dioxus-core" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "anyhow", - "const_format", - "dioxus-core-types", - "futures-channel", - "futures-util", - "generational-box", - "longest-increasing-subsequence", - "rustc-hash 2.1.1", - "rustversion", - "serde", - "slab", - "slotmap", - "subsecond", - "tracing", - "warnings", -] - -[[package]] -name = "dioxus-core-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "convert_case", - "dioxus-rsx", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dioxus-core-types" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" - -[[package]] -name = "dioxus-devtools" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools-types", - "dioxus-signals", - "serde", - "serde_json", - "subsecond", - "thiserror 2.0.17", - "tracing", - "tungstenite", - "warnings", -] - -[[package]] -name = "dioxus-devtools-types" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "serde", - "subsecond-types", -] - -[[package]] -name = "dioxus-document" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "dioxus-core-macro", - "dioxus-core-types", - "dioxus-html", - "futures-channel", - "futures-util", - "generational-box", - "lazy-js-bundle 0.7.0-rc.1", - "serde", - "serde_json", - "tracing", -] - -[[package]] -name = "dioxus-fullstack" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "anyhow", - "async-stream", - "async-tungstenite", - "axum", - "axum-core", - "base64", - "bytes", - "ciborium", - "const-str", - "const_format", - "content_disposition", - "derive_more", - "dioxus-asset-resolver", - "dioxus-cli-config", - "dioxus-core", - "dioxus-fullstack-core", - "dioxus-fullstack-macro", - "dioxus-hooks", - "dioxus-html", - "dioxus-signals", - "form_urlencoded", - "futures", - "futures-channel", - "futures-util", - "gloo-net", - "headers", - "http", - "http-body", - "http-body-util", - "js-sys", - "mime", - "pin-project", - "reqwest", - "rustversion", - "send_wrapper", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "thiserror 2.0.17", - "tokio-util", - "tracing", - "tungstenite", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "xxhash-rust", -] - -[[package]] -name = "dioxus-fullstack-core" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "anyhow", - "axum-core", - "base64", - "ciborium", - "dioxus-core", - "dioxus-document", - "dioxus-history", - "dioxus-hooks", - "dioxus-signals", - "futures-channel", - "futures-util", - "generational-box", - "http", - "inventory", - "serde", - "serde_json", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "dioxus-fullstack-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "const_format", - "convert_case", - "proc-macro2", - "quote", - "syn", - "xxhash-rust", -] - -[[package]] -name = "dioxus-history" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "tracing", -] - -[[package]] -name = "dioxus-hooks" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "dioxus-signals", - "futures-channel", - "futures-util", - "generational-box", - "rustversion", - "slab", - "tracing", - "warnings", -] - -[[package]] -name = "dioxus-html" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "async-trait", - "bytes", - "dioxus-core", - "dioxus-core-macro", - "dioxus-core-types", - "dioxus-hooks", - "dioxus-html-internal-macro", - "enumset", - "euclid", - "futures-channel", - "futures-util", - "generational-box", - "keyboard-types", - "lazy-js-bundle 0.7.0-rc.1", - "rustversion", - "tracing", -] - -[[package]] -name = "dioxus-html-internal-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dioxus-interpreter-js" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "js-sys", - "lazy-js-bundle 0.7.0-rc.1", - "rustc-hash 2.1.1", - "sledgehammer_bindgen", - "sledgehammer_utils", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "dioxus-logger" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-cli-config", - "tracing", - "tracing-subscriber", - "tracing-wasm", -] - -[[package]] -name = "dioxus-primitives" -version = "0.0.1" -source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" -dependencies = [ - "dioxus", - "dioxus-time", - "lazy-js-bundle 0.6.2", - "time", - "tracing", -] - -[[package]] -name = "dioxus-router" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-macro", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-router-macro", - "dioxus-signals", - "percent-encoding", - "rustversion", - "tracing", - "url", -] - -[[package]] -name = "dioxus-router-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "base16", - "digest", - "proc-macro2", - "quote", - "sha2", - "slab", - "syn", -] - -[[package]] -name = "dioxus-rsx" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn", -] - -[[package]] -name = "dioxus-signals" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "futures-channel", - "futures-util", - "generational-box", - "parking_lot", - "rustc-hash 2.1.1", - "tracing", - "warnings", -] - -[[package]] -name = "dioxus-stores" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "dioxus-signals", - "dioxus-stores-macro", -] - -[[package]] -name = "dioxus-stores-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dioxus-time" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" -dependencies = [ - "dioxus", - "futures", - "gloo-timers", - "tokio", -] - -[[package]] -name = "dioxus-web" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-types", - "dioxus-devtools", - "dioxus-document", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", - "dioxus-signals", - "futures-channel", - "futures-util", - "generational-box", - "gloo-timers", - "js-sys", - "lazy-js-bundle 0.7.0-rc.1", - "rustc-hash 2.1.1", - "send_wrapper", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enumset" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b07a8dfbbbfc0064c0a6bdf9edcf966de6b1c33ce344bdeca3b41615452634" -dependencies = [ - "enumset_derive", -] - -[[package]] -name = "enumset_derive" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e744e4ea338060faee68ed933e46e722fb7f3617e722a5772d7e856d8b3ce" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "euclid" -version = "0.22.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad9cdb4b747e485a12abb0e6566612956c7a1bafa3bdb8d682c5b6d403589e48" -dependencies = [ - "num-traits", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generational-box" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "parking_lot", - "tracing", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasi 0.14.7+wasi-0.2.4", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - -[[package]] -name = "gloo-net" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06f627b1a58ca3d42b45d6104bf1e1a03799df472df00988b6ba21accc10580" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils", - "http", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror 1.0.69", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "half" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" -dependencies = [ - "cfg-if", - "crunchy", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - -[[package]] -name = "headers" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" -dependencies = [ - "base64", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" -dependencies = [ - "http", -] - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-util" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "indexmap" -version = "2.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" -dependencies = [ - "equivalent", - "hashbrown", -] - -[[package]] -name = "infer" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" -dependencies = [ - "cfb", -] - -[[package]] -name = "inventory" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" -dependencies = [ - "rustversion", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "jni-sys" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "lazy-js-bundle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" - -[[package]] -name = "lazy-js-bundle" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.176" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "litrs" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "longest-increasing-subsequence" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "macro-string" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "manganis" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "const-serialize", - "manganis-core", - "manganis-macro", -] - -[[package]] -name = "manganis-core" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "const-serialize", - "dioxus-cli-config", - "dioxus-core-types", - "serde", -] - -[[package]] -name = "manganis-macro" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dunce", - "macro-string", - "manganis-core", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matchit" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memfd" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" -dependencies = [ - "rustix", -] - -[[package]] -name = "memmap2" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" -dependencies = [ - "libc", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "multer" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http", - "httparse", - "memchr", - "mime", - "spin", - "version_check", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[package]] -name = "ndk-context" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" - -[[package]] -name = "ndk-sys" -version = "0.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_enum" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" -version = "0.1.0" -dependencies = [ - "dioxus", - "dioxus-primitives", - "time", - "tracing", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "potential_utf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "proc-macro-crate" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "psl-types" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" - -[[package]] -name = "publicsuffix" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" -dependencies = [ - "idna", - "psl-types", -] - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash 2.1.1", - "rustls", - "socket2", - "thiserror 2.0.17", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" -dependencies = [ - "bytes", - "getrandom 0.3.3", - "lru-slab", - "rand", - "ring", - "rustc-hash 2.1.1", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.17", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[package]] -name = "raw-window-handle" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex-automata" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" - -[[package]] -name = "reqwest" -version = "0.12.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" -dependencies = [ - "base64", - "bytes", - "cookie", - "cookie_store", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" -dependencies = [ - "futures-core", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_path_to_error" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" -dependencies = [ - "itoa", - "serde", - "serde_core", -] - -[[package]] -name = "serde_qs" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3faaf9e727533a19351a43cc5a8de957372163c7d35cc48c90b75cdda13c352" -dependencies = [ - "percent-encoding", - "serde", - "thiserror 2.0.17", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "sledgehammer_bindgen" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e83e178d176459c92bc129cfd0958afac3ced925471b889b3a75546cfc4133" -dependencies = [ - "sledgehammer_bindgen_macro", - "wasm-bindgen", -] - -[[package]] -name = "sledgehammer_bindgen_macro" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "sledgehammer_utils" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debdd4b83524961983cea3c55383b3910fd2f24fd13a188f5b091d2d504a61ae" -dependencies = [ - "rustc-hash 1.1.0", -] - -[[package]] -name = "slotmap" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" -dependencies = [ - "serde", - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "subsecond" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "js-sys", - "libc", - "libloading", - "memfd", - "memmap2", - "serde", - "subsecond-types", - "thiserror 2.0.17", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "subsecond-types" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "serde", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" -dependencies = [ - "deranged", - "itoa", - "js-sys", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.47.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" -dependencies = [ - "backtrace", - "bytes", - "io-uring", - "libc", - "mio", - "pin-project-lite", - "slab", - "socket2", - "windows-sys 0.59.0", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" -dependencies = [ - "bytes", - "futures-core", - "futures-io", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" -dependencies = [ - "serde_core", -] - -[[package]] -name = "toml_edit" -version = "0.23.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" -dependencies = [ - "indexmap", - "toml_datetime", - "toml_parser", - "winnow", -] - -[[package]] -name = "toml_parser" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" -dependencies = [ - "winnow", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "once_cell", - "regex-automata", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", -] - -[[package]] -name = "tracing-wasm" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" -dependencies = [ - "tracing", - "tracing-subscriber", - "wasm-bindgen", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tungstenite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadc29d668c91fcc564941132e17b28a7ceb2f3ebf0b9dae3e03fd7a6748eb0d" -dependencies = [ - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "sha1", - "thiserror 2.0.17", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicase" -version = "2.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" - -[[package]] -name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "warnings" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64f68998838dab65727c9b30465595c6f7c953313559371ca8bf31759b3680ad" -dependencies = [ - "pin-project", - "tracing", - "warnings-macro", -] - -[[package]] -name = "warnings-macro" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "winapi-util" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "xxhash-rust" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[patch.unused]] -name = "dioxus-dx-wire-format" -version = "0.7.0-rc.1" -source = "git+https://github.com/DioxusLabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" diff --git a/packages/playground/server/template/Cargo.toml b/packages/playground/server/template/Cargo.toml deleted file mode 100644 index 7b08c2e9d4..0000000000 --- a/packages/playground/server/template/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -# This excludes the template from the rest of the workspaces. -[workspace] - -[package] -name = "play-5f1689ca-25e2-3fea-96d4-75ad3e26efa9" -version = "0.1.0" -edition = "2024" - -[dependencies] -dioxus = { git = "https://github.com/DioxusLabs/dioxus", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false, features = ["router"] } -time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } -tracing = "0.1.41" -wasm-bindgen = "=0.2.100" -web-sys = { version = "0.3", features = ["Location"] } - -[profile.dev.package."*"] -opt-level = 3 -debug = false -strip = true - -[profile.dev.package.dioxus-devtools] -opt-level = 3 -debug = true -strip = true - -[profile.dev.package.dioxus-web] -opt-level = 3 -debug = true -strip = true - -[patch.crates-io] -dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } -generational-box = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/playground/server/template/Dioxus.toml b/packages/playground/server/template/Dioxus.toml deleted file mode 100644 index feb660d85c..0000000000 --- a/packages/playground/server/template/Dioxus.toml +++ /dev/null @@ -1,22 +0,0 @@ -[application] -name = "5f1689ca-25e2-3fea-96d4-75ad3e26efa9" -default_platform = "web" -out_dir = "dist" -asset_dir = "assets" -hot_reload = false - -[web.app] -base_path = "built/5f1689ca-25e2-3fea-96d4-75ad3e26efa9" - -title = "Dioxus Playground" -[web.watcher] -index_on_404 = true -watch_path = ["src", "examples"] -[web.resource] -style = [] -script = [] -[web.resource.dev] -script = [] -[application.plugins] -available = true -required = [] From d649c4fe77835095392f4ee028254dbe02881f8b Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 10 Oct 2025 12:01:19 -0500 Subject: [PATCH 34/58] Fix prebuild --- .github/workflows/fly-deploy.yml | 12 +---- Cargo.lock | 15 +++++- fly.toml | 8 ++-- packages/playground/playground/src/build.rs | 16 +------ .../playground/src/components/header.rs | 36 +++++++------- packages/playground/playground/src/ws.rs | 2 +- packages/playground/server/Cargo.toml | 1 + packages/playground/server/src/app.rs | 2 +- .../playground/server/src/build/builder.rs | 1 + .../playground/server/src/build/watcher.rs | 9 ++-- packages/playground/server/src/main.rs | 2 +- packages/playground/server/src/ws.rs | 10 +--- .../playground/server/template/src/main.rs | 48 +++++++++++++++---- 13 files changed, 89 insertions(+), 73 deletions(-) diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml index 577523eda8..b0c246edee 100644 --- a/.github/workflows/fly-deploy.yml +++ b/.github/workflows/fly-deploy.yml @@ -1,25 +1,17 @@ # See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ name: Fly Deploy - on: push: branches: - main - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - jobs: deploy: name: Deploy app - runs-on: blacksmith-4vcpu-ubuntu-2404 - concurrency: deploy-group # optional: ensure only one action runs at a time + runs-on: ubuntu-latest + concurrency: deploy-group # optional: ensure only one action runs at a time steps: - uses: actions/checkout@v4 - with: - submodules: "recursive" - uses: superfly/flyctl-actions/setup-flyctl@master - run: flyctl deploy --remote-only env: diff --git a/Cargo.lock b/Cargo.lock index 9f6bfcb3b8..9e4878ccfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2054,7 +2054,7 @@ dependencies = [ "dioxus-devtools", "dioxus-document", "dioxus-html", - "dioxus-primitives", + "dioxus-primitives 0.0.1 (git+https://github.com/ealmloff/components?branch=bump-dioxus-git)", "dioxus-rsx", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", @@ -2088,6 +2088,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "dioxus-primitives" +version = "0.0.1" +source = "git+https://github.com/DioxusLabs/components#3571d90aa55773c59b05119d9fff8879da6b8a3d" +dependencies = [ + "dioxus", + "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=0.7)", + "lazy-js-bundle 0.6.2", + "time", + "tracing", +] + [[package]] name = "dioxus-router" version = "0.7.0-rc.1" @@ -6753,6 +6765,7 @@ dependencies = [ "dioxus-devtools-types", "dioxus-dx-wire-format", "dioxus-logger", + "dioxus-primitives 0.0.1 (git+https://github.com/DioxusLabs/components)", "example-projects", "fs_extra", "futures", diff --git a/fly.toml b/fly.toml index 2bbb8593bb..f619502666 100644 --- a/fly.toml +++ b/fly.toml @@ -1,4 +1,4 @@ -# fly.toml app configuration file generated for docsite-playground on 2025-02-04T15:44:00-08:00 +# fly.toml app configuration file generated for docsite-playground-thrumming-sun-6870 on 2025-09-25T12:53:35-05:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # @@ -6,7 +6,7 @@ app = 'docsite-playground' primary_region = 'lax' kill_signal = 'SIGINT' -kill_timeout = '5s' +kill_timeout = '300s' [build] @@ -38,6 +38,6 @@ kill_timeout = '5s' soft_limit = 20 [[vm]] - memory = '3gb' + memory = '2gb' cpu_kind = 'shared' - cpus = 2 + cpus = 8 diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index a253287674..94c8264fbe 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -10,6 +10,7 @@ pub(crate) enum BuildStage { NotStarted, Starting, Waiting(Duration), + Queued(usize), Building(model::BuildStage), Finished(Result), } @@ -18,7 +19,7 @@ impl BuildStage { pub fn is_running(&self) -> bool { matches!( self, - Self::Starting | Self::Building(..) | Self::Waiting(..) + Self::Starting | Self::Building(..) | Self::Waiting(..) | Self::Queued(..) ) } @@ -64,7 +65,6 @@ impl BuildStage { #[derive(Debug, Clone, Copy)] pub(crate) struct BuildState { stage: Signal, - queue_position: Signal>, diagnostics: Signal>, previous_build_id: Signal>, } @@ -77,7 +77,6 @@ impl BuildState { } else { BuildStage::NotStarted }), - queue_position: Signal::new(None), diagnostics: Signal::new(Vec::new()), previous_build_id: Signal::new(None), } @@ -86,7 +85,6 @@ impl BuildState { /// Reset the build state to it's default. pub fn reset(&mut self) { self.stage.set(BuildStage::NotStarted); - self.queue_position.set(None); self.diagnostics.clear(); self.previous_build_id.set(None); } @@ -101,16 +99,6 @@ impl BuildState { self.stage.set(stage); } - /// Get the current queue position. - pub fn queue_position(&self) -> Option { - (self.queue_position)() - } - - /// Set the queue position. - pub fn set_queue_position(&mut self, position: Option) { - self.queue_position.set(position); - } - /// Get the diagnostics signal. pub fn diagnostics(&self) -> Signal> { self.diagnostics diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 46b9696547..9cbd0700ac 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -31,7 +31,6 @@ pub fn Header( // Left pane header div { id: "dxp-header-left", - style: if let Some(val) = pane_left_width() { "width:{val}px;" }, // Examples button/menu Select:: { @@ -81,7 +80,6 @@ pub fn Header( // Right pane header div { id: "dxp-header-right", - style: if let Some(val) = pane_right_width() { "width:{val}px;" } else { "".to_string() }, // Share button Button { @@ -140,25 +138,23 @@ fn Progress() -> Element { let build = use_context::(); // Generate the loading message. - let message = use_memo(move || { - let compiling = build.stage().get_compiling_stage(); - if let Some((crates_compiled, total_crates, current_crate)) = compiling { - return format!("{crates_compiled}/{total_crates}"); - } - - match build.stage() { - BuildStage::NotStarted => "Waiting".to_string(), - BuildStage::Starting => "Starting".to_string(), - BuildStage::Waiting(time) => { - format!("Waiting {}s", time.as_secs()) - } - BuildStage::Building(build_stage) => match build_stage { - model::BuildStage::RunningBindgen => "Binding".to_string(), - model::BuildStage::Other => "Computing".to_string(), - model::BuildStage::Compiling { .. } => unreachable!(), - }, - BuildStage::Finished(_) => "Finished!".to_string(), + let message = use_memo(move || match build.stage() { + BuildStage::NotStarted => "Waiting".to_string(), + BuildStage::Queued(position) => format!("Queued ({position})"), + BuildStage::Starting => "Starting".to_string(), + BuildStage::Waiting(time) => { + format!("Waiting {}s", time.as_secs()) } + BuildStage::Building(build_stage) => match build_stage { + model::BuildStage::RunningBindgen => "Binding".to_string(), + model::BuildStage::Other => "Computing".to_string(), + model::BuildStage::Compiling { + crates_compiled, + total_crates, + .. + } => format!("{crates_compiled}/{total_crates}"), + }, + BuildStage::Finished(_) => "Finished!".to_string(), }); rsx! { diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index 9f1b093d19..729d862282 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -43,7 +43,7 @@ impl Socket { pub fn handle_message(mut build: BuildState, message: SocketMessage) -> bool { match message { SocketMessage::BuildStage(stage) => build.set_stage(BuildStage::Building(stage)), - SocketMessage::QueuePosition(position) => build.set_queue_position(Some(position)), + SocketMessage::QueuePosition(position) => build.set_stage(BuildStage::Queued(position)), SocketMessage::BuildFinished(BuildResult::Failed(failure)) => { build.set_stage(BuildStage::Finished(Err(failure))); return true; diff --git a/packages/playground/server/Cargo.toml b/packages/playground/server/Cargo.toml index bda91a54bc..48c57d829d 100644 --- a/packages/playground/server/Cargo.toml +++ b/packages/playground/server/Cargo.toml @@ -36,6 +36,7 @@ tower_governor = "0.8.0" governor = "0.10.1" rustix = { version = "1.1.2", features = ["process"] } dashmap = "6.1.0" +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false, features = ["router"] } [features] tracing = ["tokio/tracing", "dep:console-subscriber"] diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 7cd97df4e8..99967f7469 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -35,7 +35,7 @@ const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB /// Max memory usage of dx during a build before it is killed. const DEFAULT_DX_MEMORY_LIMIT: u64 = 5 * 1024 * 1024 * 1024; // 5 GB /// Max seconds a dx build can take before it is killed. -const DEFAULT_DX_BUILD_TIMEOUT: u64 = 30; // 30 seconds +const DEFAULT_DX_BUILD_TIMEOUT: u64 = 5 * 60; // 5 minutes /// Max size of the target directory before it is cleaned. const DEFAULT_TARGET_DIR_SIZE: u64 = 3 * 1024 * 1024 * 1024; // 3 GB diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index aa853acd43..0fb2a3c45c 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -335,6 +335,7 @@ fn process_build_messages( while let Some(Ok(line)) = stdout_reader.next() { logs.push(line.clone()); + tracing::info!("{line}"); patch = patch.or(process_dx_message(env, request, line)); } diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index d0baf05356..92b160177f 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -22,11 +22,12 @@ pub fn start_build_watcher( ) -> UnboundedSender { let (tx, mut rx) = mpsc::unbounded_channel(); + let mut builder = Builder::new(env, is_building); + if let Err(err) = builder.update_component_library() { + tracing::error!("failed to update component library: {err}"); + } + tokio::spawn(async move { - let mut builder = Builder::new(env, is_building); - if let Err(err) = builder.update_component_library() { - tracing::error!("failed to update component library: {err}"); - } let mut pending_builds = VecDeque::new(); loop { diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index d1eae5436b..5e669766a9 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -13,7 +13,7 @@ use dioxus_logger::tracing::{Level, error, info}; use share::{get_shared_project, share_project}; use std::{net::SocketAddr, sync::atomic::Ordering, time::Duration}; use tokio::{net::TcpListener, time::Instant}; -use tower::{ServiceBuilder, buffer::BufferLayer, limit::RateLimitLayer}; +use tower::{ServiceBuilder, buffer::BufferLayer}; use tower_governor::{GovernorLayer, governor::GovernorConfigBuilder}; use tower_http::{compression::CompressionLayer, cors::CorsLayer}; diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index 094f38ff79..d80983e4dd 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -50,16 +50,8 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { continue; }; - // Start a new build, stopping any existing ones. + // Start a new build if let SocketMessage::BuildRequest { code, previous_build_id } = socket_msg { - if let Some(ref request) = current_build { - let result = state.build_queue_tx.send(BuildCommand::Stop { id: request.id }); - if result.is_err() { - error!(build_id = ?request.id, "failed to send build stop signal for new build request"); - continue; - } - } - // Rate limit the build requests by ip if let Err(n) = state.build_govener.check_key(&ip) { let wait_time = n.wait_time_from(QuantaClock::default().now()); diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs index 5cfde7b728..149be2bcc1 100644 --- a/packages/playground/server/template/src/main.rs +++ b/packages/playground/server/template/src/main.rs @@ -1,7 +1,12 @@ -//! A basic counter example demonstrating signals, -//! event handlers, and basic rendering. +//! A simple example showcasing the dx-components library. +mod components; + +use components::calendar::*; use dioxus::prelude::*; +use time::{macros::date, Date, UtcDateTime}; + +static THEME: Asset = asset!("/assets/dx-components-theme.css"); fn main() { dioxus::launch(App); @@ -9,13 +14,40 @@ fn main() { #[component] fn App() -> Element { - let mut count = use_signal(|| 0); - + let mut selected_date = use_signal(|| None::); + let mut view_date = use_signal(|| UtcDateTime::now().date()); rsx! { - p { "Count: {count*2}" } - div { style: "display: flex;", - button { onclick: move |_| count -= 1, "-" } - button { onclick: move |_| count += 1, "+" } + document::Stylesheet { href: THEME } + div { + display: "flex", + align_items: "center", + justify_content: "center", + height: "100vh", + width: "100vw", + div { + width: "258px", + Calendar { + selected_date: selected_date(), + on_date_change: move |date| { + selected_date.set(date); + }, + view_date: view_date(), + on_view_change: move |new_view: Date| { + view_date.set(new_view); + }, + min_date: date!(1995 - 07 - 21), + max_date: date!(2035 - 09 - 11), + CalendarHeader { + CalendarNavigation { + CalendarPreviousMonthButton {} + CalendarSelectMonth {} + CalendarSelectYear {} + CalendarNextMonthButton {} + } + } + CalendarGrid {} + } + } } } } From e4176e977c6315f20457d7b8df6e2bff8dda965d Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Fri, 10 Oct 2025 12:10:35 -0500 Subject: [PATCH 35/58] use dioxus 0.7-rc.1 in the playground --- .../server/template/snippets/Cargo.toml | 10 ++-- .../playground/server/template/src/main.rs | 53 ------------------- 2 files changed, 3 insertions(+), 60 deletions(-) delete mode 100644 packages/playground/server/template/src/main.rs diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index b322139256..21aa23ef37 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -7,8 +7,8 @@ version = "0.1.0" edition = "2024" [dependencies] -dioxus = { git = "https://github.com/DioxusLabs/dioxus", rev = "05c0980", features = ["web", "router"] } -dioxus-primitives = { git = "https://github.com/DioxusLabs/components", rev = "2901fd2", version = "0.0.1", default-features = false, features = ["router"] } +dioxus = { version = "0.7.0-rc.1", features = ["web", "router"] } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", rev = "3571d90", version = "0.0.1", default-features = false, features = ["router"] } time = { version = "0.3.44", features = ["std", "macros", "wasm-bindgen"] } tracing = "0.1.41" wasm-bindgen = "=0.2.100" @@ -29,11 +29,7 @@ opt-level = 3 debug = true strip = true -[patch.crates-io] -dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } + dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } subsecond = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/packages/playground/server/template/src/main.rs b/packages/playground/server/template/src/main.rs deleted file mode 100644 index 149be2bcc1..0000000000 --- a/packages/playground/server/template/src/main.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! A simple example showcasing the dx-components library. - -mod components; - -use components::calendar::*; -use dioxus::prelude::*; -use time::{macros::date, Date, UtcDateTime}; - -static THEME: Asset = asset!("/assets/dx-components-theme.css"); - -fn main() { - dioxus::launch(App); -} - -#[component] -fn App() -> Element { - let mut selected_date = use_signal(|| None::); - let mut view_date = use_signal(|| UtcDateTime::now().date()); - rsx! { - document::Stylesheet { href: THEME } - div { - display: "flex", - align_items: "center", - justify_content: "center", - height: "100vh", - width: "100vw", - div { - width: "258px", - Calendar { - selected_date: selected_date(), - on_date_change: move |date| { - selected_date.set(date); - }, - view_date: view_date(), - on_view_change: move |new_view: Date| { - view_date.set(new_view); - }, - min_date: date!(1995 - 07 - 21), - max_date: date!(2035 - 09 - 11), - CalendarHeader { - CalendarNavigation { - CalendarPreviousMonthButton {} - CalendarSelectMonth {} - CalendarSelectYear {} - CalendarNextMonthButton {} - } - } - CalendarGrid {} - } - } - } - } -} From 391786d9d7cb204ad2fb7bcdd8759866d192846f Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 13 Oct 2025 09:21:06 -0500 Subject: [PATCH 36/58] fix hotreloading --- packages/playground/playground/src/hotreload.rs | 12 ++---------- packages/playground/playground/src/lib.rs | 10 +++++++--- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/playground/playground/src/hotreload.rs b/packages/playground/playground/src/hotreload.rs index 95e7d259f7..55f3be8211 100644 --- a/packages/playground/playground/src/hotreload.rs +++ b/packages/playground/playground/src/hotreload.rs @@ -85,14 +85,6 @@ impl HotReload { }; } - fn full_rebuild(&mut self, code: String) -> HotReloadError { - *self.cached_parse.write() = CachedParse { - raw: code, - templates: HashMap::new(), - }; - HotReloadError::NeedsRebuild - } - pub fn process_file_change( &mut self, new_code: String, @@ -106,7 +98,7 @@ impl HotReload { let changes = match diff_rsx(&new_file, &cached_file) { Some(rsx_calls) => rsx_calls, - None => return Err(self.full_rebuild(new_code)), + None => return Err(HotReloadError::NeedsRebuild), }; let mut out_templates = Vec::new(); @@ -131,7 +123,7 @@ impl HotReload { // if the template is not hotreloadable, we need to do a full rebuild let Some(results) = hotreload_result else { - return Err(self.full_rebuild(new_code)); + return Err(HotReloadError::NeedsRebuild); }; let mut cached = self.cached_parse.write(); diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 4201775c03..7019cf8442 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -106,14 +106,18 @@ pub fn Playground( if build.stage().is_running() || !monaco_ready() { return; } - hot_reload.set_needs_rebuild(false); // Update hot reload let code = editor::monaco::get_current_model_value(); let socket_url = urls.socket.to_string(); - match start_build(build, socket_url, code).await { - Ok(success) => hot_reload.set_needs_rebuild(!success), + match start_build(build, socket_url, code.clone()).await { + Ok(success) => { + if success { + hot_reload.set_starting_code(&code); + } + hot_reload.set_needs_rebuild(!success) + } Err(error) => errors.push_from_app_error(error), } }); From 62bdabae41203de02c688702e1a31df494852e65 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 13 Oct 2025 09:52:45 -0500 Subject: [PATCH 37/58] cleanup --- packages/playground/playground/src/build.rs | 14 --- .../playground/src/components/logs.rs | 2 - .../playground/src/components/panes.rs | 22 +---- packages/playground/server/src/app.rs | 88 +++++++++---------- .../playground/server/src/build/builder.rs | 1 - .../playground/server/src/build/cleanup.rs | 48 ++++++---- .../playground/server/src/build/watcher.rs | 2 - .../server/template/snippets/Cargo.toml | 14 +-- 8 files changed, 83 insertions(+), 108 deletions(-) diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index 94c8264fbe..f2e7303c67 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -46,20 +46,6 @@ impl BuildStage { None } - - /// Extract the compiling stage info if available. - pub fn get_compiling_stage(&self) -> Option<(usize, usize, String)> { - if let Self::Building(model::BuildStage::Compiling { - crates_compiled, - total_crates, - current_crate, - }) = self - { - return Some((*crates_compiled, *total_crates, current_crate.to_string())); - } - - None - } } #[derive(Debug, Clone, Copy)] diff --git a/packages/playground/playground/src/components/logs.rs b/packages/playground/playground/src/components/logs.rs index 42a1c37558..0c6762e49b 100644 --- a/packages/playground/playground/src/components/logs.rs +++ b/packages/playground/playground/src/components/logs.rs @@ -10,8 +10,6 @@ pub fn Logs() -> Element { rsx! { div { - id: "logs", - // Main failure reason. if let Some(message) = err_message { Log { diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index 62ae57e16d..5cc42d271b 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -1,7 +1,6 @@ -use crate::build::{BuildStage, BuildState}; +use crate::build::BuildState; use dioxus::prelude::*; use dioxus_document::eval; -// use dioxus_sdk::utils::{timing::use_debounce, window::use_window_size}; use super::Logs; @@ -31,21 +30,6 @@ pub fn Panes( let mut dragging = use_signal(|| false); let mut mouse_data = use_signal(DraggableData::default); - // // Reset the panes slider on window resize. - // // TODO: This is annoying for the user, it should instead just recalculate the size from previous data. - // let window_size = use_window_size(); - // let mut reset_panes_debounce = use_debounce(std::time::Duration::from_millis(200), move |_| { - // spawn(async move { - // pane_left_width.set(None); - // pane_right_width.set(None); - // }); - // }); - - // use_effect(move || { - // window_size(); - // reset_panes_debounce.action(()); - // }); - // Handle retrieving required data from dom elements and enabling drag. let draggable_mousedown = move |e: Event| async move { dragging.set(true); @@ -107,7 +91,7 @@ pub fn Panes( // Left Pane div { id: "dxp-panes-left", - style: if let Some(val) = pane_left_width() { "width:{val}px;" }, + width: if let Some(val) = pane_left_width() { "{val}px;" }, } // Draggable div { @@ -132,7 +116,7 @@ pub fn Panes( // Right Pane div { id: "dxp-panes-right", - style: if let Some(val) = pane_right_width() { "width:{val}px;" }, + width: if let Some(val) = pane_right_width() { "{val}px;" }, // Viewport if build_stage.is_err() { diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 99967f7469..bcbb148d97 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -13,9 +13,11 @@ use governor::{ }; use std::{ env, + fmt::Display, net::IpAddr, num::NonZeroU32, path::PathBuf, + str::FromStr, sync::{Arc, atomic::AtomicBool}, time::Duration, }; @@ -83,6 +85,10 @@ impl EnvVars { let build_template_path = Self::get_build_template_path(); let shutdown_delay = Self::get_shutdown_delay(); let gist_auth_token = Self::get_gist_auth_token(); + let max_built_dir_size = Self::get_max_built_dir_size(); + let max_target_dir_size = Self::get_max_target_dir_size(); + let dx_memory_limit = Self::get_dx_memory_limit(); + let dx_build_timeout = Self::get_dx_build_timeout(); Self { production, @@ -94,10 +100,10 @@ impl EnvVars { PathBuf::from("./temp/") }, shutdown_delay, - max_built_dir_size: DEFAULT_BUILT_DIR_SIZE, - max_target_dir_size: DEFAULT_TARGET_DIR_SIZE, - dx_memory_limit: DEFAULT_DX_MEMORY_LIMIT, - dx_build_timeout: DEFAULT_DX_BUILD_TIMEOUT, + max_built_dir_size, + max_target_dir_size, + dx_memory_limit, + dx_build_timeout, gist_auth_token: gist_auth_token.unwrap_or_default(), } } @@ -116,53 +122,22 @@ impl EnvVars { /// Get the production environment variable. fn get_production_env() -> bool { - let production = env::var("PRODUCTION") - .ok() - .and_then(|v| v.parse::().ok()) - .unwrap_or(false); - - info!("is the server is running in production? {production}"); - production + get_env_or("PRODUCTION", false) } /// Get the serve port from environment or default. fn get_port_env() -> u16 { - let mut port = DEFAULT_PORT; - match env::var("PORT") { - Ok(v) => { - port = v - .parse() - .expect("the `PORT` environment variable should be a number") - } - Err(_) => info!( - "`PORT` environment variable not set; defaulting to `{}`", - port - ), - } - - port + get_env_or("PORT", DEFAULT_PORT) } /// Get the build template path from environment or default. fn get_build_template_path() -> PathBuf { - let mut build_template_path = PathBuf::from(DEFAULT_BUILD_TEMPLATE_PATH); - match env::var("BUILD_TEMPLATE_PATH") { - Ok(v) => build_template_path = PathBuf::from(v), - Err(_) => info!( - "`BUILD_TEMPLATE_PATH` environment variable is not set; defaulting to `{:?}`", - build_template_path - ), - } - - build_template_path + get_env_parsed("BUILD_TEMPLATE_PATH").unwrap_or_else(|| DEFAULT_BUILD_TEMPLATE_PATH.into()) } /// Get the server shutdown delay from the environment. fn get_shutdown_delay() -> Option { - let shutdown_delay = env::var("SHUTDOWN_DELAY") - .ok() - .and_then(|v| v.parse().ok()) - .map(Duration::from_secs); + let shutdown_delay = get_env_parsed::("SHUTDOWN_DELAY").map(Duration::from_secs); if shutdown_delay.is_none() { warn!("`SHUTDOWN_DELAY` environment variable is not set; the server will not turn off") @@ -173,14 +148,39 @@ impl EnvVars { /// Get the GitHub Gists authentication token from the environment. fn get_gist_auth_token() -> Option { - let gist_auth_token = env::var("GIST_AUTH_TOKEN").ok(); + get_env_parsed("GIST_AUTH_TOKEN") + } - if gist_auth_token.is_none() { - warn!("`GIST_AUTH_TOKEN` environment variable is not set") - } + /// Get the max size of the built directory from the environment or default. + fn get_max_built_dir_size() -> u64 { + get_env_or("MAX_BUILT_DIR_SIZE", DEFAULT_BUILT_DIR_SIZE) + } - gist_auth_token + /// Get the max size of the target directory from the environment or default. + fn get_max_target_dir_size() -> u64 { + get_env_or("MAX_TARGET_DIR_SIZE", DEFAULT_TARGET_DIR_SIZE) } + + /// Get the max memory limit for dx during a build from the environment or default. + fn get_dx_memory_limit() -> u64 { + get_env_or("DX_MEMORY_LIMIT", DEFAULT_DX_MEMORY_LIMIT) + } + + /// Get the max seconds a dx build can take before it is killed from the environment or default. + fn get_dx_build_timeout() -> u64 { + get_env_or("DX_BUILD_TIMEOUT", DEFAULT_DX_BUILD_TIMEOUT) + } +} + +fn get_env_parsed(key: &str) -> Option { + env::var(key).ok().and_then(|v| v.parse().ok()) +} + +fn get_env_or(key: &str, default: F) -> F { + get_env_parsed(key).unwrap_or_else(|| { + info!("`{key}` environment variable not set; defaulting to `{default}`"); + default + }) } /// The state of the server application. diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 0fb2a3c45c..aa853acd43 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -335,7 +335,6 @@ fn process_build_messages( while let Some(Ok(line)) = stdout_reader.next() { logs.push(line.clone()); - tracing::info!("{line}"); patch = patch.or(process_dx_message(env, request, line)); } diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index ee3bec9a6c..c7146f9c0f 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -36,15 +36,10 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { while let Some(item) = dir.next_entry().await? { let path = item.path(); - let pathname = path.file_name().unwrap().to_string_lossy(); - - // Always cache the examples - don't remove those. - if example_projects::get_example_projects() - .iter() - .any(|p| p.id().to_string() == pathname) - { + let Some(filename) = path.file_name() else { continue; - } + }; + let filename = filename.to_string_lossy().to_string(); let metadata = item.metadata().await; let time_elapsed = metadata @@ -52,27 +47,50 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { .and_then(|c| c.elapsed().map_err(io::Error::other)); let size = dir_size(&path).await; if let (Ok(time_elapsed), Ok(size)) = (time_elapsed, size) { - dirs_with_size.push((item, time_elapsed, size)); + dirs_with_size.push((filename, item, time_elapsed, size)); } else { - tracing::trace!("skipping cleanup of {pathname} due to error reading metadata") + tracing::trace!("skipping cleanup of {filename} due to error reading metadata") } } // Find the total size of the built directory. - let total_size: u64 = dirs_with_size.iter().map(|(_, _, size)| *size).sum(); + let total_size: u64 = dirs_with_size.iter().map(|(_, _, _, size)| *size).sum(); // If it exceeds the max, sort by oldest and remove until under the limit. if total_size > env.max_built_dir_size { - dirs_with_size.sort_by_key(|(_, time_elapsed, _)| *time_elapsed); + dirs_with_size.sort_by_key(|(_, _, time_elapsed, _)| *time_elapsed); let mut size = total_size; - for (item, _, dir_size) in dirs_with_size { + for (pathname, item, _, dir_size) in dirs_with_size { if size <= env.max_built_dir_size { break; } let path = item.path(); - _ = tokio::fs::remove_dir_all(&path).await; - size -= dir_size; + // Always cache the examples - only remove the patches + if example_projects::get_example_projects() + .iter() + .any(|p| p.id().to_string() == pathname) + { + // Find all files in the wasm folder that contain patch and remove them + let wasm_path = path.join("wasm"); + if wasm_path.exists() { + let mut wasm_dir = tokio::fs::read_dir(&wasm_path).await?; + while let Some(entry) = wasm_dir.next_entry().await? { + let entry_path = entry.path(); + if let Some(name) = entry_path.file_name() { + if name.to_string_lossy().contains("patch") { + let patch_size = + entry.metadata().await.map(|m| m.len()).unwrap_or(0); + _ = tokio::fs::remove_file(&entry_path).await; + size -= patch_size; + } + } + } + } + } else { + _ = tokio::fs::remove_dir_all(&path).await; + size -= dir_size; + } } } diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index 92b160177f..ef828cf968 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -34,7 +34,6 @@ pub fn start_build_watcher( select! { // Handle incoming build commands. Some(command) = rx.recv() => { - tracing::info!("got command: {command:?}"); match command { BuildCommand::Start { request } => start_build(&mut builder, &mut pending_builds, request), BuildCommand::Stop { id } => stop_build(&mut builder, &mut pending_builds, id), @@ -73,7 +72,6 @@ fn start_build( /// - Iterate through queue looking for a matching id. /// If matching id found, update queue positions *behind* matching queue and remove matched item. fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque, id: Uuid) { - tracing::info!("stopping build {id:?}"); // Check if the ongoing build is the cancelled build. let current_build_id = builder.current_build().map(|b| b.id); if let Some(current_build_id) = current_build_id { diff --git a/packages/playground/server/template/snippets/Cargo.toml b/packages/playground/server/template/snippets/Cargo.toml index 21aa23ef37..9c65352a44 100644 --- a/packages/playground/server/template/snippets/Cargo.toml +++ b/packages/playground/server/template/snippets/Cargo.toml @@ -15,24 +15,16 @@ wasm-bindgen = "=0.2.100" web-sys = { version = "0.3", features = ["Location"] } [profile.dev.package."*"] -opt-level = 3 +opt-level = 'z' debug = false strip = true [profile.dev.package.dioxus-devtools] -opt-level = 3 +opt-level = 'z' debug = true strip = true [profile.dev.package.dioxus-web] -opt-level = 3 +opt-level = 'z' debug = true strip = true - - -dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } -generational-box = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } From 7a21d74d07c728a2eb5c8ceb630893ea25c10347 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 13 Oct 2025 12:08:46 -0500 Subject: [PATCH 38/58] better error formatting --- Cargo.lock | 84 +++++---- packages/playground/model/src/lib.rs | 7 +- packages/playground/model/src/server.rs | 2 + packages/playground/playground/Cargo.toml | 4 +- packages/playground/playground/assets/dxp.css | 5 + .../playground/src/components/logs.rs | 172 ++++++++++++++---- .../playground/src/components/panes.rs | 12 +- .../src/dx_components/accordion/component.rs | 68 +++++++ .../src/dx_components/accordion/mod.rs | 2 + .../src/dx_components/accordion/style.css | 95 ++++++++++ .../playground/src/dx_components/mod.rs | 1 + .../playground/server/src/build/builder.rs | 1 + .../playground/server/src/build/cleanup.rs | 2 +- 13 files changed, 370 insertions(+), 85 deletions(-) create mode 100644 packages/playground/playground/src/dx_components/accordion/component.rs create mode 100644 packages/playground/playground/src/dx_components/accordion/mod.rs create mode 100644 packages/playground/playground/src/dx_components/accordion/style.css diff --git a/Cargo.lock b/Cargo.lock index 9e4878ccfa..f94915b9dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -77,6 +77,16 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi-parser" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43e7fd8284f025d0bd143c2855618ecdf697db55bde39211e5c9faec7669173" +dependencies = [ + "heapless 0.8.0", + "nom", +] + [[package]] name = "anstream" version = "0.6.21" @@ -1496,7 +1506,7 @@ dependencies = [ [[package]] name = "dioxus-cli-config" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "wasm-bindgen", ] @@ -1518,7 +1528,7 @@ source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73 [[package]] name = "dioxus-core" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "anyhow", "const_format", @@ -1540,7 +1550,7 @@ dependencies = [ [[package]] name = "dioxus-core-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", @@ -1552,7 +1562,7 @@ dependencies = [ [[package]] name = "dioxus-core-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" [[package]] name = "dioxus-desktop" @@ -1611,7 +1621,7 @@ dependencies = [ [[package]] name = "dioxus-devtools" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -1631,7 +1641,7 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-core", "serde", @@ -1755,7 +1765,7 @@ dependencies = [ [[package]] name = "dioxus-document" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -1906,7 +1916,7 @@ dependencies = [ [[package]] name = "dioxus-hooks" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1922,7 +1932,7 @@ dependencies = [ [[package]] name = "dioxus-html" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "async-trait", "bytes", @@ -1949,7 +1959,7 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -1960,7 +1970,7 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-core", "dioxus-core-types", @@ -2046,6 +2056,7 @@ dependencies = [ name = "dioxus-playground" version = "0.1.0" dependencies = [ + "ansi-parser", "base64 0.22.1", "dioxus", "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2054,7 +2065,7 @@ dependencies = [ "dioxus-devtools", "dioxus-document", "dioxus-html", - "dioxus-primitives 0.0.1 (git+https://github.com/ealmloff/components?branch=bump-dioxus-git)", + "dioxus-primitives", "dioxus-rsx", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", @@ -2076,18 +2087,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "dioxus-primitives" -version = "0.0.1" -source = "git+https://github.com/ealmloff/components?branch=bump-dioxus-git#72dac8db64acc02bd5dd702aafc97c892f41dd7a" -dependencies = [ - "dioxus", - "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=0.7)", - "lazy-js-bundle 0.6.2", - "time", - "tracing", -] - [[package]] name = "dioxus-primitives" version = "0.0.1" @@ -2137,7 +2136,7 @@ dependencies = [ [[package]] name = "dioxus-rsx" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -2291,7 +2290,7 @@ dependencies = [ [[package]] name = "dioxus-signals" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "dioxus-core", "futures-channel", @@ -3152,7 +3151,7 @@ dependencies = [ [[package]] name = "generational-box" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "parking_lot", "tracing", @@ -3522,6 +3521,15 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3607,13 +3615,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", - "hash32", + "hash32 0.2.1", "rustc_version", "serde", "spin", "stable_deref_trait", ] +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -4276,7 +4294,7 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" [[package]] name = "lazy_static" @@ -5647,7 +5665,7 @@ dependencies = [ "cobs", "embedded-io 0.4.0", "embedded-io 0.6.1", - "heapless", + "heapless 0.7.17", "serde", ] @@ -6765,7 +6783,7 @@ dependencies = [ "dioxus-devtools-types", "dioxus-dx-wire-format", "dioxus-logger", - "dioxus-primitives 0.0.1 (git+https://github.com/DioxusLabs/components)", + "dioxus-primitives", "example-projects", "fs_extra", "futures", @@ -7101,7 +7119,7 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "js-sys", "libc", @@ -7119,7 +7137,7 @@ dependencies = [ [[package]] name = "subsecond-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" dependencies = [ "serde", ] diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index 7dc5ee39f1..4dc40365a7 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -72,21 +72,22 @@ impl SocketMessage { } /// A cargo diagnostic -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)] pub struct CargoDiagnostic { pub target_crate: Option, pub level: CargoLevel, pub message: String, pub spans: Vec, + pub rendered: Option, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)] pub enum CargoLevel { Error, Warning, } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)] pub struct CargoDiagnosticSpan { pub is_primary: bool, pub line_start: usize, diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 0bb8732756..d9d2c926a1 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -85,6 +85,7 @@ impl TryFrom for CargoDiagnostic { level, message, spans, + rendered: diagnostic.rendered, }) } } @@ -118,6 +119,7 @@ impl TryFrom for CargoDiagnostic { level, message, spans, + rendered: value.rendered, }) } } diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index ab4ca6ba8f..0af2dc4186 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -34,13 +34,13 @@ gloo-utils = { workspace = true } wasm-bindgen = { version = "0.2.99", features = ["serde-serialize"] } miniz_oxide = { version = "0.8.0", features = ["std"] } base64 = "0.22.1" +ansi-parser = "0.9.1" syn = { workspace = true } proc-macro2 = "1.0.89" - example-projects = { workspace = true } -dioxus-primitives = { git = "https://github.com/ealmloff/components", branch = "bump-dioxus-git", version = "0.0.1", default-features = false } +dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false } tracing = "0.1.41" [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index 6458ae3735..3f20b364d0 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -110,10 +110,13 @@ #dxp-panes-right { display: flex; + flex-direction: column; + align-items: center; width: 50%; min-width: 100px; background-color: var(--dxp-bg-light-darker); position: relative; + overflow-y: scroll; } #dxp-panes-right > p { @@ -139,7 +142,9 @@ #dxp-panes-right > #dxp-viewport { width: 100%; + height: 100%; background-color: white; + color: black; } #dxp-iframe { diff --git a/packages/playground/playground/src/components/logs.rs b/packages/playground/playground/src/components/logs.rs index 0c6762e49b..b123d349d9 100644 --- a/packages/playground/playground/src/components/logs.rs +++ b/packages/playground/playground/src/components/logs.rs @@ -1,4 +1,8 @@ +use std::collections::HashMap; + use crate::build::BuildState; +use crate::dx_components::accordion::*; +use ansi_parser::AnsiParser; use dioxus::prelude::*; use model::{CargoDiagnosticSpan, CargoLevel}; @@ -6,25 +10,37 @@ use model::{CargoDiagnosticSpan, CargoLevel}; pub fn Logs() -> Element { let build = use_context::(); let diagnostics = build.diagnostics()(); + let diagnostics_with_spans = diagnostics.into_iter().filter(|d| !d.spans.is_empty()); + // Deduplicate diagnostics + let diagnostics_with_spans: HashMap<_, _> = diagnostics_with_spans + .enumerate() + .map(|(i, item)| (item, i)) + .collect(); + let mut diagnostics_with_spans: Vec<_> = diagnostics_with_spans.into_iter().collect(); + diagnostics_with_spans.sort_by_key(|(_, id)| *id); + let diagnostics_with_spans = diagnostics_with_spans.into_iter().map(|(item, _)| item); let err_message = build.stage().err_message(); rsx! { - div { - // Main failure reason. - if let Some(message) = err_message { - Log { - level: CargoLevel::Error, - message, - spans: Vec::new(), - } + // Main failure reason. + if let Some(message) = err_message { + h2 { + "{message}" } + } + // Diagnostics + Accordion { + allow_multiple_open: true, + horizontal: false, // Log diagnostics - for diagnostic in diagnostics { + for (i, diagnostic) in diagnostics_with_spans.enumerate() { Log { + index: i, level: diagnostic.level, message: diagnostic.message, spans: diagnostic.spans, + rendered: diagnostic.rendered } } } @@ -32,51 +48,127 @@ pub fn Logs() -> Element { } #[component] -fn Log(level: CargoLevel, message: String, spans: Vec) -> Element { +fn Log( + index: usize, + level: CargoLevel, + message: String, + spans: Vec, + rendered: Option, +) -> Element { let level = match level { CargoLevel::Error => ("Error", "level-error"), CargoLevel::Warning => ("Warning", "level-warn"), }; rsx! { - div { - class: "log", - // Level - p { - class: "log-level", + AccordionItem { index, + AccordionTrigger { + display: "flex", + justify_content: "space-between", + align_items: "center", + padding: "0.5rem 1rem", + "{message}" span { - class: "{level.1}", "{level.0}" } } - - div { - class: "log-codeblock", - // Message - p { - class: "log-message", - "{message}", + AccordionContent { + RenderedLog { + rendered } + } + } + } +} + +#[component] +fn RenderedLog(rendered: Option) -> Element { + let Some(rendered) = rendered else { + return rsx! {}; + }; - for span in spans { - if let Some(label) = span.label { - p { - class: "log-span", - "-" - span { - class: "level-info", - " {span.line_start}" - } - ":" - span { - class: "level-info", - "{span.column_start}" - } - " {label}" - } - } + let mut fg_color = [0u8, 0, 0]; + let mut bg_color = [255u8, 255, 255]; + let mut bold = false; + let iter = rendered.ansi_parse().filter_map(|output| match output { + ansi_parser::Output::TextBlock(text) => { + let background_color = + format!("rgb({}, {}, {})", bg_color[0], bg_color[1], bg_color[2]); + let color = format!("rgb({}, {}, {})", fg_color[0], fg_color[1], fg_color[2]); + Some(rsx! { + span { + background_color, + color, + font_weight: if bold { 400 }, + {text} } + }) + } + ansi_parser::Output::Escape(ansi_parser::AnsiSequence::SetGraphicsMode(mode)) => { + match mode.as_slice() { + [0] => { + fg_color = [0u8, 0, 0]; + bg_color = [255u8, 255, 255]; + bold = false; + } + [1] => { + bold = true; + } + [38, 5, rgb_color] => fg_color = color_index_to_rgb(*rgb_color), + [48, 5, rgb_color] => bg_color = color_index_to_rgb(*rgb_color), + _ => {} } + None + } + other => { + tracing::info!("other: {other:?}"); + None + } + }); + + rsx! {pre { {iter} }} +} + +fn color_index_to_rgb(index: u8) -> [u8; 3] { + match index { + // Standard colors (0-15) + 0 => [0, 0, 0], // Black + 1 => [128, 0, 0], // Red + 2 => [0, 128, 0], // Green + 3 => [128, 128, 0], // Yellow + 4 => [0, 0, 128], // Blue + 5 => [128, 0, 128], // Magenta + 6 => [0, 128, 128], // Cyan + 7 => [192, 192, 192], // White + 8 => [128, 128, 128], // Bright Black (Gray) + 9 => [255, 0, 0], // Bright Red + 10 => [0, 255, 0], // Bright Green + 11 => [255, 255, 0], // Bright Yellow + 12 => [0, 0, 255], // Bright Blue + 13 => [255, 0, 255], // Bright Magenta + 14 => [0, 255, 255], // Bright Cyan + 15 => [255, 255, 255], // Bright White + + // 216-color cube (16-231) + 16..=231 => { + let cube_index = index - 16; + let r = cube_index / 36; + let g = (cube_index % 36) / 6; + let b = cube_index % 6; + + // Map 0-5 to RGB values + let value_map = [0, 95, 135, 175, 215, 255]; + [ + value_map[r as usize], + value_map[g as usize], + value_map[b as usize], + ] + } + + // Grayscale ramp (232-255) + 232..=255 => { + let gray = 8 + (index - 232) * 10; + [gray, gray, gray] } } } diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index 5cc42d271b..077e5f66ba 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -119,18 +119,18 @@ pub fn Panes( width: if let Some(val) = pane_right_width() { "{val}px;" }, // Viewport - if build_stage.is_err() { - Logs {} - } else if let Some(url) = built_page_url() { - div { id: "dxp-viewport", + div { id: "dxp-viewport", + if build_stage.is_err() { + Logs {} + } else if let Some(url) = built_page_url() { iframe { id: "dxp-iframe", src: "{url}", pointer_events: if dragging() { "none" } else { "all" }, } + } else { + p { "Click `Rebuild` to start a build!" } } - } else { - p { "Click `Rebuild` to start a build!" } } } } diff --git a/packages/playground/playground/src/dx_components/accordion/component.rs b/packages/playground/playground/src/dx_components/accordion/component.rs new file mode 100644 index 0000000000..f9c44a92c0 --- /dev/null +++ b/packages/playground/playground/src/dx_components/accordion/component.rs @@ -0,0 +1,68 @@ +use dioxus::prelude::*; +use dioxus_primitives::accordion::{ + self, AccordionContentProps, AccordionItemProps, AccordionProps, AccordionTriggerProps, +}; + +#[component] +pub fn Accordion(props: AccordionProps) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + accordion::Accordion { + class: "accordion", + id: props.id, + allow_multiple_open: props.allow_multiple_open, + disabled: props.disabled, + collapsible: props.collapsible, + horizontal: props.horizontal, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn AccordionItem(props: AccordionItemProps) -> Element { + rsx! { + accordion::AccordionItem { + class: "accordion-item", + disabled: props.disabled, + default_open: props.default_open, + on_change: props.on_change, + on_trigger_click: props.on_trigger_click, + index: props.index, + attributes: props.attributes, + {props.children} + } + } +} + +#[component] +pub fn AccordionTrigger(props: AccordionTriggerProps) -> Element { + rsx! { + accordion::AccordionTrigger { + class: "accordion-trigger", + id: props.id, + attributes: props.attributes, + {props.children} + svg { + class: "accordion-expand-icon", + view_box: "0 0 24 24", + xmlns: "http://www.w3.org/2000/svg", + polyline { points: "6 9 12 15 18 9" } + } + } + } +} + +#[component] +pub fn AccordionContent(props: AccordionContentProps) -> Element { + rsx! { + accordion::AccordionContent { + class: "accordion-content", + style: "--collapsible-content-width: 140px", + id: props.id, + attributes: props.attributes, + {props.children} + } + } +} diff --git a/packages/playground/playground/src/dx_components/accordion/mod.rs b/packages/playground/playground/src/dx_components/accordion/mod.rs new file mode 100644 index 0000000000..9a8ae55652 --- /dev/null +++ b/packages/playground/playground/src/dx_components/accordion/mod.rs @@ -0,0 +1,2 @@ +mod component; +pub use component::*; \ No newline at end of file diff --git a/packages/playground/playground/src/dx_components/accordion/style.css b/packages/playground/playground/src/dx_components/accordion/style.css new file mode 100644 index 0000000000..5ce995a44d --- /dev/null +++ b/packages/playground/playground/src/dx_components/accordion/style.css @@ -0,0 +1,95 @@ +.accordion-trigger { + display: flex; + width: 100%; + box-sizing: border-box; + flex-direction: row; + align-items: center; + justify-content: space-between; + padding: 0; + padding-top: 1rem; + padding-bottom: 1rem; + border: none; + background-color: transparent; + color: var(--secondary-color-4); + outline: none; + text-align: left; +} + +.accordion-trigger:focus-visible { + border: none; + box-shadow: inset 0 0 0 2px var(--focused-border-color); +} + +.accordion-trigger:hover { + cursor: pointer; + text-decoration-line: underline; +} + +.accordion-content { + display: grid; + height: 0; +} + +.accordion-content[data-open="false"] { + animation: accordion-slide-down 300ms cubic-bezier(0.87, 0, 0.13, 1) + forwards; +} + +.accordion-content[data-open="true"] { + animation: accordion-slide-up 300ms cubic-bezier(0.87, 0, 0.13, 1) forwards; +} + +@keyframes accordion-slide-down { + from { + height: var(--collapsible-content-width); + } + + to { + height: 0; + } +} + +@keyframes accordion-slide-up { + from { + height: 0; + } + + to { + height: var(--collapsible-content-width); + } +} + +.accordion-item { + overflow: hidden; + box-sizing: border-box; + border-bottom: 1px solid var(--primary-color-6); + margin-top: 1px; + width: 100%; +} + +.accordion-item:first-child { + margin-top: 0; +} + +.accordion-item:last-child { + border-bottom: none; +} + +.accordion-expand-icon { + width: 20px; + height: 20px; + fill: none; + stroke: var(--secondary-color-4); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; + transition: rotate 150ms cubic-bezier(0.4, 0, 0.2, 1); +} + +.accordion-item[data-open="true"] .accordion-expand-icon { + rotate: 180deg; +} + +.accordion { + width: 100%; +} diff --git a/packages/playground/playground/src/dx_components/mod.rs b/packages/playground/playground/src/dx_components/mod.rs index 34c1064068..a3f57f1644 100644 --- a/packages/playground/playground/src/dx_components/mod.rs +++ b/packages/playground/playground/src/dx_components/mod.rs @@ -2,3 +2,4 @@ pub mod dialog; pub mod button; pub mod select; +pub mod accordion; diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index aa853acd43..07e3d7baf7 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -124,6 +124,7 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result, return Ok(None); } + tracing::info!("checking clean up"); // Check if we need to clean up old builds before starting a new one. if let Err(e) = super::cleanup::check_cleanup(&env).await { warn!("failed to clean built projects: {e}"); diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index c7146f9c0f..d90161e17b 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -43,7 +43,7 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { let metadata = item.metadata().await; let time_elapsed = metadata - .and_then(|m| m.created().or_else(|_| m.modified())) + .and_then(|m| m.modified()) .and_then(|c| c.elapsed().map_err(io::Error::other)); let size = dir_size(&path).await; if let (Ok(time_elapsed), Ok(size)) = (time_elapsed, size) { From 15e1a33f80a8120085a58b8eb6f199b1f9a65f57 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 13 Oct 2025 12:23:46 -0500 Subject: [PATCH 39/58] fix text contrast --- packages/playground/playground/src/components/logs.rs | 1 + .../playground/playground/src/dx_components/accordion/style.css | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/playground/playground/src/components/logs.rs b/packages/playground/playground/src/components/logs.rs index b123d349d9..d351a46b59 100644 --- a/packages/playground/playground/src/components/logs.rs +++ b/packages/playground/playground/src/components/logs.rs @@ -67,6 +67,7 @@ fn Log( justify_content: "space-between", align_items: "center", padding: "0.5rem 1rem", + color: "black", "{message}" span { "{level.0}" diff --git a/packages/playground/playground/src/dx_components/accordion/style.css b/packages/playground/playground/src/dx_components/accordion/style.css index 5ce995a44d..7a21a4efeb 100644 --- a/packages/playground/playground/src/dx_components/accordion/style.css +++ b/packages/playground/playground/src/dx_components/accordion/style.css @@ -79,7 +79,7 @@ width: 20px; height: 20px; fill: none; - stroke: var(--secondary-color-4); + stroke: black; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2; From 19e02dd728d76e13887a39320ad3b7907fabe36e Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 08:58:33 -0500 Subject: [PATCH 40/58] clean up some dead code --- .github/workflows/fly-deploy.yml | 11 +++++++++-- packages/docsite/assets/main.css | 18 ------------------ packages/docsite/src/main.rs | 3 --- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml index b0c246edee..5b1ed6c23e 100644 --- a/.github/workflows/fly-deploy.yml +++ b/.github/workflows/fly-deploy.yml @@ -5,13 +5,20 @@ on: push: branches: - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: deploy: name: Deploy app - runs-on: ubuntu-latest - concurrency: deploy-group # optional: ensure only one action runs at a time + runs-on: blacksmith-4vcpu-ubuntu-2404 + concurrency: deploy-group # optional: ensure only one action runs at a time steps: - uses: actions/checkout@v4 + with: + submodules: "recursive" - uses: superfly/flyctl-actions/setup-flyctl@master - run: flyctl deploy --remote-only env: diff --git a/packages/docsite/assets/main.css b/packages/docsite/assets/main.css index 555658543e..f26d373add 100644 --- a/packages/docsite/assets/main.css +++ b/packages/docsite/assets/main.css @@ -46,21 +46,6 @@ flex-direction: column; } -/* .full-chapter { - padding-top: 12px; - padding-bottom: 12px; -} */ -/* .full-chapter:not(:last-child) { - &:where([data-theme="light"], [data-theme="light"] *) { - border-bottom: 1px solid #3b3d3e29; - } -} - -.full-chapter:not(:last-child) { - &:where([data-theme="dark"], [data-theme="dark"] *) { - border-bottom: 1px solid #a4a9ac7d; - } -} */ html { &:where([data-theme="dark"], [data-theme="dark"] *) { @@ -208,9 +193,6 @@ It's so unliklely anyone is copying text on mobile that we can just hide it background-color: #1e1e1e; } -.dioxus-blog-post h1 { - /* text-align: center; */ -} .dioxus-blog-post :where(h2:not(:is(h1 + h2))):not( diff --git a/packages/docsite/src/main.rs b/packages/docsite/src/main.rs index d7752e663d..f9fd3a57a9 100644 --- a/packages/docsite/src/main.rs +++ b/packages/docsite/src/main.rs @@ -195,9 +195,6 @@ fn Head() -> Element { #[derive(Clone, Routable, PartialEq, Eq, Serialize, Deserialize, Debug)] #[rustfmt::skip] pub enum Route { - // #[layout(HeadLayout)] - // #[layout(HeaderLayout)] - // #[layout(FooterLayout)] #[layout(HeaderFooter)] #[route("/")] Homepage {}, From f569a75a0c126ec138b5471e296531b023f68c24 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 09:08:21 -0500 Subject: [PATCH 41/58] clean up and switch to stores --- packages/playground/playground/Cargo.toml | 2 +- packages/playground/playground/src/build.rs | 57 ++++++++----------- .../playground/src/components/header.rs | 19 ++++--- .../playground/src/components/logs.rs | 16 ++++-- .../playground/src/components/panes.rs | 6 +- .../src/dx_components/button/component.rs | 4 -- .../src/dx_components/button/style.css | 17 ------ .../playground/src/editor/monaco.rs | 5 +- .../playground/playground/src/hotreload.rs | 34 ++++++----- packages/playground/playground/src/lib.rs | 48 +++++++++------- packages/playground/playground/src/ws.rs | 10 +++- packages/playground/server/src/app.rs | 4 +- .../playground/server/src/build/builder.rs | 1 - .../server/src/{serve.rs => built.rs} | 3 +- packages/playground/server/src/main.rs | 23 +++++--- 15 files changed, 124 insertions(+), 125 deletions(-) rename packages/playground/server/src/{serve.rs => built.rs} (94%) diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index 0af2dc4186..b789194439 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -14,7 +14,7 @@ uuid = { workspace = true } thiserror = { workspace = true } # Dioxus -dioxus = { workspace = true, features = ["web"] } +dioxus = { workspace = true, features = ["web", "router"] } dioxus-document = { workspace = true } dioxus-sdk = { workspace = true, features = ["util", "time", "window"] } diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index f2e7303c67..b3b56e1346 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -5,7 +5,7 @@ use dioxus::prelude::*; use model::{AppError, CargoDiagnostic, Project, SocketMessage}; use uuid::Uuid; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Store)] pub(crate) enum BuildStage { NotStarted, Starting, @@ -48,66 +48,59 @@ impl BuildStage { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Store)] pub(crate) struct BuildState { - stage: Signal, - diagnostics: Signal>, - previous_build_id: Signal>, + stage: BuildStage, + diagnostics: Vec, + previous_build_id: Option, } impl BuildState { pub fn new(project: &Project) -> Self { Self { - stage: Signal::new(if project.prebuilt { + stage: if project.prebuilt { BuildStage::Finished(Ok(project.id())) } else { BuildStage::NotStarted - }), - diagnostics: Signal::new(Vec::new()), - previous_build_id: Signal::new(None), + }, + diagnostics: Vec::new(), + previous_build_id: None, } } +} +#[store(pub)] +impl Store { /// Reset the build state to it's default. - pub fn reset(&mut self) { - self.stage.set(BuildStage::NotStarted); - self.diagnostics.clear(); - self.previous_build_id.set(None); + fn reset(&mut self) { + self.stage().set(BuildStage::NotStarted); + self.diagnostics().clear(); + self.previous_build_id().set(None); } /// Get the current stage. - pub fn stage(&self) -> BuildStage { - (self.stage)() + fn get_stage(&self) -> BuildStage { + self.stage().cloned() } /// Set the build stage. - pub fn set_stage(&mut self, stage: BuildStage) { - self.stage.set(stage); - } - - /// Get the diagnostics signal. - pub fn diagnostics(&self) -> Signal> { - self.diagnostics + fn set_stage(&mut self, stage: BuildStage) { + self.stage().set(stage); } /// Add another diagnostic to the current list. - pub fn push_diagnostic(&mut self, diagnostic: CargoDiagnostic) { - self.diagnostics.push(diagnostic); - } - - /// Get the previous build ID signal. - pub fn previous_build_id(&self) -> Signal> { - self.previous_build_id + fn push_diagnostic(&mut self, diagnostic: CargoDiagnostic) { + self.diagnostics().push(diagnostic); } } /// Start a build and handle updating the build signals according to socket messages. pub async fn start_build( - mut build: BuildState, + mut build: Store, socket_url: String, code: String, ) -> Result { - let stage = build.stage(); + let stage = build.get_stage(); // Reset build state if stage.is_running() { return Err(AppError::BuildIsAlreadyRunning); @@ -144,7 +137,7 @@ pub async fn start_build( socket.close().await; let mut success = false; - if let BuildStage::Finished(Ok(_)) = build.stage() { + if let BuildStage::Finished(Ok(_)) = build.get_stage() { success = true; }; diff --git a/packages/playground/playground/src/components/header.rs b/packages/playground/playground/src/components/header.rs index 9cbd0700ac..741f078d87 100644 --- a/packages/playground/playground/src/components/header.rs +++ b/packages/playground/playground/src/components/header.rs @@ -1,10 +1,11 @@ -use crate::build::{BuildStage, BuildState}; +use crate::build::{BuildStage, BuildState, BuildStateStoreImplExt}; use crate::components::icons::LoadingSpinner; use crate::dx_components::button::*; use crate::dx_components::select::*; +use crate::hotreload::HotReloadStoreImplExt; use crate::share_code::copy_share_link; -use crate::HotReload; use crate::{Errors, PlaygroundUrls}; +use crate::{ErrorsStoreImplExt, HotReload}; use dioxus::prelude::*; use model::api::ApiClient; use model::Project; @@ -19,10 +20,10 @@ pub fn Header( file_name: ReadSignal, ) -> Element { let api_client: Signal = use_context(); - let mut build: BuildState = use_context(); + let mut build: Store = use_context(); let mut project: Signal = use_context(); - let mut errors: Errors = use_context(); - let mut hot_reload: HotReload = use_context(); + let mut errors: Store = use_context(); + let mut hot_reload: Store = use_context(); let mut share_btn_text = use_signal(|| "Share"); @@ -110,7 +111,7 @@ pub fn Header( // Run button Button { variant: ButtonVariant::Outline, - "data-disabled": build.stage().is_running(), + "data-disabled": build.get_stage().is_running(), display: "flex", flex_direction: "row", align_items: "between", @@ -121,7 +122,7 @@ pub fn Header( on_rebuild.call(()); }, - if build.stage().is_running() { + if build.get_stage().is_running() { Progress {} } else { "Rebuild" @@ -135,10 +136,10 @@ pub fn Header( #[component] fn Progress() -> Element { - let build = use_context::(); + let build = use_context::>(); // Generate the loading message. - let message = use_memo(move || match build.stage() { + let message = use_memo(move || match build.get_stage() { BuildStage::NotStarted => "Waiting".to_string(), BuildStage::Queued(position) => format!("Queued ({position})"), BuildStage::Starting => "Starting".to_string(), diff --git a/packages/playground/playground/src/components/logs.rs b/packages/playground/playground/src/components/logs.rs index d351a46b59..1aba2f91b1 100644 --- a/packages/playground/playground/src/components/logs.rs +++ b/packages/playground/playground/src/components/logs.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::build::BuildState; +use crate::build::{BuildState, BuildStateStoreExt}; use crate::dx_components::accordion::*; use ansi_parser::AnsiParser; use dioxus::prelude::*; @@ -8,9 +8,10 @@ use model::{CargoDiagnosticSpan, CargoLevel}; #[component] pub fn Logs() -> Element { - let build = use_context::(); - let diagnostics = build.diagnostics()(); - let diagnostics_with_spans = diagnostics.into_iter().filter(|d| !d.spans.is_empty()); + let build = use_context::>(); + let diagnostics = build.diagnostics(); + let diagnostics = diagnostics.read(); + let diagnostics_with_spans = diagnostics.iter().filter(|d| !d.spans.is_empty()); // Deduplicate diagnostics let diagnostics_with_spans: HashMap<_, _> = diagnostics_with_spans .enumerate() @@ -18,8 +19,11 @@ pub fn Logs() -> Element { .collect(); let mut diagnostics_with_spans: Vec<_> = diagnostics_with_spans.into_iter().collect(); diagnostics_with_spans.sort_by_key(|(_, id)| *id); - let diagnostics_with_spans = diagnostics_with_spans.into_iter().map(|(item, _)| item); - let err_message = build.stage().err_message(); + let diagnostics_with_spans = diagnostics_with_spans + .into_iter() + .map(|(item, _)| item) + .cloned(); + let err_message = build.stage().read().err_message(); rsx! { // Main failure reason. diff --git a/packages/playground/playground/src/components/panes.rs b/packages/playground/playground/src/components/panes.rs index 077e5f66ba..3e00f8defa 100644 --- a/packages/playground/playground/src/components/panes.rs +++ b/packages/playground/playground/src/components/panes.rs @@ -1,4 +1,4 @@ -use crate::build::BuildState; +use crate::build::{BuildState, BuildStateStoreExt}; use dioxus::prelude::*; use dioxus_document::eval; @@ -26,7 +26,7 @@ pub fn Panes( pane_right_width: Signal>, built_page_url: Memo>, ) -> Element { - let build = use_context::(); + let build = use_context::>(); let mut dragging = use_signal(|| false); let mut mouse_data = use_signal(DraggableData::default); @@ -120,7 +120,7 @@ pub fn Panes( // Viewport div { id: "dxp-viewport", - if build_stage.is_err() { + if build_stage().is_err() { Logs {} } else if let Some(url) = built_page_url() { iframe { diff --git a/packages/playground/playground/src/dx_components/button/component.rs b/packages/playground/playground/src/dx_components/button/component.rs index 05221e1c06..a7998a2da3 100644 --- a/packages/playground/playground/src/dx_components/button/component.rs +++ b/packages/playground/playground/src/dx_components/button/component.rs @@ -6,9 +6,7 @@ pub enum ButtonVariant { #[default] Primary, Secondary, - Destructive, Outline, - Ghost, } impl ButtonVariant { @@ -16,9 +14,7 @@ impl ButtonVariant { match self { ButtonVariant::Primary => "primary", ButtonVariant::Secondary => "secondary", - ButtonVariant::Destructive => "destructive", ButtonVariant::Outline => "outline", - ButtonVariant::Ghost => "ghost", } } } diff --git a/packages/playground/playground/src/dx_components/button/style.css b/packages/playground/playground/src/dx_components/button/style.css index e8e7e2fb91..9ab6176974 100644 --- a/packages/playground/playground/src/dx_components/button/style.css +++ b/packages/playground/playground/src/dx_components/button/style.css @@ -28,15 +28,6 @@ background-color: var(--primary-color-4); } -.button[data-style="ghost"] { - background-color: transparent; - color: var(--secondary-color-4); -} -.button[data-style="ghost"]:hover { - background-color: var(--primary-color-5); - color: var(--secondary-color-1); -} - .button[data-style="outline"] { border: 1px solid var(--primary-color-6); background-color: var(--light, var(--primary-color)) @@ -47,14 +38,6 @@ background-color: var(--primary-color-4); } -.button[data-style="destructive"] { - background-color: var(--primary-error-color); - color: var(--contrast-error-color); -} -.button[data-style="destructive"]:hover { - background-color: var(--secondary-error-color); -} - .button[data-disabled="true"] { background-color: var(--primary-color-6); color: var(--secondary-color-5); diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index eb30ab1eb1..6dd54e83c0 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -1,4 +1,5 @@ use crate::hotreload::HotReload; +use crate::hotreload::HotReloadStoreImplExt; use dioxus::prelude::*; use dioxus_sdk::window::theme::Theme; use model::{CargoDiagnostic, CargoLevel}; @@ -18,7 +19,7 @@ pub fn monaco_loader_src(folder: Asset) -> String { } /// Use monaco code markers for build diagnostics. -pub fn set_monaco_markers(diagnostics: Signal>) { +pub fn set_monaco_markers(diagnostics: impl Writable>) { let mut markers = Vec::new(); for diagnostic in diagnostics.read().iter() { let severity = match diagnostic.level { @@ -54,7 +55,7 @@ pub fn on_monaco_load( folder: Asset, system_theme: Theme, contents: &str, - mut hot_reload: HotReload, + mut hot_reload: Store, mut monaco_ready: Signal, on_model_changed: Callback, onbuild_callback: Callback<()>, diff --git a/packages/playground/playground/src/hotreload.rs b/packages/playground/playground/src/hotreload.rs index 55f3be8211..ffc51c589e 100644 --- a/packages/playground/playground/src/hotreload.rs +++ b/packages/playground/playground/src/hotreload.rs @@ -12,7 +12,7 @@ use std::{collections::HashMap, fmt::Display, path::Path}; use syn::spanned::Spanned as _; /// Atempts to hot reload and returns true if a full rebuild is needed. -pub fn attempt_hot_reload(mut hot_reload: HotReload, new_code: &str) { +pub fn attempt_hot_reload(mut hot_reload: Store, new_code: &str) { // Process any potential hot -eloadable changes and send them to the iframe web client. let result = hot_reload.process_file_change(new_code.to_string()); match result { @@ -50,12 +50,13 @@ pub fn send_hot_reload(hr_msg: HotReloadMsg) { _ = e.send(hr_msg); } -#[derive(Clone, Copy)] +#[derive(Store)] pub struct HotReload { - needs_rebuild: Signal, - cached_parse: Signal, + needs_rebuild: bool, + cached_parse: CachedParse, } +#[derive(Store)] struct CachedParse { raw: String, templates: HashMap, @@ -65,34 +66,38 @@ impl HotReload { pub fn new() -> Self { Self { cached_parse: { - Signal::new(CachedParse { + CachedParse { raw: String::new(), templates: HashMap::new(), - }) + } }, - needs_rebuild: Signal::new(true), + needs_rebuild: true, } } +} - pub fn set_needs_rebuild(&mut self, needs_rebuild: bool) { - self.needs_rebuild.set(needs_rebuild); +#[store(pub)] +impl Store { + fn set_needs_rebuild(&mut self, needs_rebuild: bool) { + self.needs_rebuild().set(needs_rebuild); } - pub fn set_starting_code(&mut self, code: &str) { - *self.cached_parse.write() = CachedParse { + fn set_starting_code(&mut self, code: &str) { + *self.cached_parse().write() = CachedParse { raw: code.to_string(), templates: HashMap::new(), }; } - pub fn process_file_change( + fn process_file_change( &mut self, new_code: String, ) -> Result, HotReloadError> { let new_file = syn::parse_file(&new_code).map_err(|_err| HotReloadError::Parse)?; let cached_file = { - let cached = &mut self.cached_parse.read(); + let cached = self.cached_parse(); + let cached = cached.read(); syn::parse_file(&cached.raw).map_err(|_err| HotReloadError::Parse)? }; @@ -126,7 +131,8 @@ impl HotReload { return Err(HotReloadError::NeedsRebuild); }; - let mut cached = self.cached_parse.write(); + let mut cached = self.cached_parse(); + let mut cached = cached.write(); for (index, template) in results.templates { if template.roots.is_empty() { continue; diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 7019cf8442..0f575e6efe 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -11,6 +11,11 @@ use std::time::Duration; use dioxus_sdk::window::theme::{use_system_theme, Theme}; +use crate::{ + build::{BuildStateStoreExt, BuildStateStoreImplExt}, + hotreload::HotReloadStoreImplExt, +}; + mod build; mod components; mod dx_components; @@ -40,9 +45,9 @@ pub fn Playground( share_code: ReadSignal>, class: Option, ) -> Element { - let mut hot_reload = use_context_provider(HotReload::new); + let mut hot_reload = use_context_provider(|| Store::new(HotReload::new())); let api_client = use_context_provider(|| Signal::new(ApiClient::new(urls.server))); - let mut errors = use_context_provider(Errors::new); + let mut errors = use_context_provider(|| Store::new(Errors::new())); let monaco_ready = use_signal(|| false); let mut show_share_warning = use_signal(|| false); @@ -50,7 +55,7 @@ pub fn Playground( // Default to the welcome project. // Project dirty determines whether the Rust-project is synced with the project in the editor. let mut project = use_context_provider(|| Signal::new(example_projects::get_welcome_project())); - let mut build = use_context_provider(|| BuildState::new(&project.read())); + let mut build = use_context_provider(|| Store::new(BuildState::new(&project.read()))); let mut project_dirty = use_signal(|| false); use_effect(move || { if project_dirty() && monaco_ready() { @@ -83,7 +88,7 @@ pub fn Playground( spawn(async move { editor::monaco::set_markers(&[]); - if build.stage().is_finished() { + if build.get_stage().is_finished() { attempt_hot_reload(hot_reload, &new_code); } }); @@ -103,7 +108,7 @@ pub fn Playground( // Handle starting a build. let on_rebuild = use_callback(move |_| { spawn(async move { - if build.stage().is_running() || !monaco_ready() { + if build.get_stage().is_running() || !monaco_ready() { return; } @@ -127,7 +132,7 @@ pub fn Playground( let built_page_url = use_memo(move || { let project = project.read(); let prebuilt_id = project.prebuilt.then_some(project.id()); - let local_id = build.stage().finished_id(); + let local_id = build.get_stage().finished_id(); let id = local_id.or(prebuilt_id)?; Some(format!("{}/built/{}", urls.server, id)) }); @@ -188,7 +193,7 @@ pub fn Playground( on_ok: move |_| { errors.pop(); }, - open: !errors.errors.is_empty(), + open: !errors.errors().is_empty(), if let Some((title, text)) = errors.last() { components::ModalContent { icon: rsx! { @@ -222,25 +227,26 @@ pub fn Playground( } /// A helper type for gracefully handling app errors and logging them. -#[derive(Clone, Copy)] +#[derive(Clone, Store)] pub struct Errors { - errors: Signal>, + errors: Vec<(String, String)>, } impl Errors { pub fn new() -> Self { - Self { - errors: Signal::new(Vec::new()), - } + Self { errors: Vec::new() } } +} - pub fn push_error(&mut self, error: (impl ToString, impl ToString)) { +#[store(pub)] +impl Store { + fn push_error(&mut self, error: (impl ToString, impl ToString)) { let error = (error.0.to_string(), error.1.to_string()); error!(?error, "an error occured and was handled gracefully"); - self.errors.push(error); + self.errors().push(error); } - pub fn push_from_app_error(&mut self, app_error: AppError) { + fn push_from_app_error(&mut self, app_error: AppError) { let error = match app_error { AppError::Parse(error) => ("Parse Error", error.to_string()), AppError::Request(error) => ("Request Error", error.to_string()), @@ -264,16 +270,16 @@ impl Errors { self.push_error(error); } - pub fn first(&self) -> Option<(String, String)> { - self.errors.first().map(|x| x.clone()) + fn first(&self) -> Option<(String, String)> { + self.errors().first().map(|x| x.clone()) } - pub fn last(&self) -> Option<(String, String)> { - self.errors.last().map(|x| x.clone()) + fn last(&self) -> Option<(String, String)> { + self.errors().last().map(|x| x.clone()) } - pub fn pop(&mut self) -> Option<(String, String)> { - self.errors.pop() + fn pop(&mut self) -> Option<(String, String)> { + self.errors().pop() } } diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index 729d862282..53a716b5bf 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -1,5 +1,9 @@ -use crate::{build::BuildStage, hotreload::send_hot_reload, BuildState}; -use dioxus::signals::ReadableExt; +use crate::{ + build::{BuildStage, BuildStateStoreExt, BuildStateStoreImplExt}, + hotreload::send_hot_reload, + BuildState, +}; +use dioxus::{signals::ReadableExt, stores::Store}; use dioxus_devtools::HotReloadMsg; use futures::{SinkExt as _, StreamExt}; use gloo_net::websocket::futures::WebSocket; @@ -40,7 +44,7 @@ impl Socket { } /// Handles a websocket message, returning true if further messages shouldn't be handled. -pub fn handle_message(mut build: BuildState, message: SocketMessage) -> bool { +pub fn handle_message(mut build: Store, message: SocketMessage) -> bool { match message { SocketMessage::BuildStage(stage) => build.set_stage(BuildStage::Building(stage)), SocketMessage::QueuePosition(position) => build.set_stage(BuildStage::Queued(position)), diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index bcbb148d97..c2da2e483e 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -224,8 +224,8 @@ impl AppState { let build_govener = Arc::new(RateLimiter::keyed( Quota::with_period(Duration::from_secs(5)) - .unwrap() - .allow_burst(NonZeroU32::new(2).unwrap()), + .expect("period is non-zero") + .allow_burst(const { NonZeroU32::new(2).unwrap() }), )); let state = Self { diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 07e3d7baf7..aa853acd43 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -124,7 +124,6 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result, return Ok(None); } - tracing::info!("checking clean up"); // Check if we need to clean up old builds before starting a new one. if let Err(e) = super::cleanup::check_cleanup(&env).await { warn!("failed to clean built projects: {e}"); diff --git a/packages/playground/server/src/serve.rs b/packages/playground/server/src/built.rs similarity index 94% rename from packages/playground/server/src/serve.rs rename to packages/playground/server/src/built.rs index 1dbe409a8b..0bf1067fca 100644 --- a/packages/playground/server/src/serve.rs +++ b/packages/playground/server/src/built.rs @@ -11,7 +11,6 @@ use uuid::Uuid; use crate::app::AppState; /// Handle providing temporary built wasm assets. -/// This should delete temporary projects after 30 seconds. pub async fn serve_built_index( State(state): State, Path(build_id): Path, @@ -21,6 +20,7 @@ pub async fn serve_built_index( let index_path = path.join("index.html"); + // Serve the file with tower_http tower_http::services::ServeFile::new(index_path) .oneshot(request) .await @@ -41,6 +41,7 @@ pub async fn serve_other_built( .join(build_id.to_string()) .join(file_path); + // Serve the file with tower_http tower_http::services::ServeFile::new(path) .oneshot(request) .await diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 5e669766a9..6ff47b0a24 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -19,7 +19,7 @@ use tower_http::{compression::CompressionLayer, cors::CorsLayer}; mod app; mod build; -mod serve; +mod builtbuilt; mod share; mod ws; @@ -34,9 +34,8 @@ async fn main() { use tracing_subscriber::{EnvFilter, fmt}; let fmt_layer = fmt::layer(); - let filter_layer = EnvFilter::try_from_default_env() - .or_else(|_| EnvFilter::try_new("info")) - .unwrap(); + let filter_layer = + EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")); tracing_subscriber::registry() .with(console_layer) @@ -54,26 +53,32 @@ async fn main() { false => ClientIpSource::ConnectInfo, }; - // Allow bursts with up to five requests per IP address - // and replenishes one element every 30 seconds + // Allow bursts with up to 240 requests per IP address + // and replenishes 120 every second. These requests are + // very cheap. Rate limiting for builds is handled seperately let governor_conf = GovernorConfigBuilder::default() .per_second(120) .burst_size(240) .finish() - .unwrap(); + .expect("neither per_second nor burst_size are zero"); // Build the routers. let built_router = Router::new() - .route("/", get(serve::serve_built_index)) - .route("/{*file_path}", get(serve::serve_other_built)); + .route("/", get(builtbuilt::serve_built_index)) + .route("/{*file_path}", get(builtbuilt::serve_other_built)); let shared_router = Router::new() .route("/", post(share_project)) .route("/{:id}", get(get_shared_project)); let app = Router::new() + // Just wait forever for the devtools to connect. We handle them through the ws route bellow. + .route("/_dioxus", get(std::future::pending::>)) + // Every build gets a websocket connection to report build progress. .route("/ws", get(ws::ws_handler)) + // The built routes for project that are cached. .nest("/built/{:build_id}", built_router) + // Routes for resolving shared projects. .nest("/shared", shared_router) .route( "/", From 6a4c12c2be18d87448872169c5e74060d00d3444 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 09:14:30 -0500 Subject: [PATCH 42/58] bump dioxus --- .github/workflows/fly-deploy.yml | 1 + .github/workflows/gh-pages.yml | 2 +- Cargo.lock | 443 +++++++++---------------- Cargo.toml | 68 ++-- README.md | 2 +- fly.toml | 2 +- packages/playground/server/src/main.rs | 6 +- 7 files changed, 188 insertions(+), 336 deletions(-) diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml index 5b1ed6c23e..577523eda8 100644 --- a/.github/workflows/fly-deploy.yml +++ b/.github/workflows/fly-deploy.yml @@ -1,6 +1,7 @@ # See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ name: Fly Deploy + on: push: branches: diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f7db1c56d1..aa7bb2ea0f 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -33,7 +33,7 @@ jobs: cache-on-failure: "false" - uses: cargo-bins/cargo-binstall@main - name: Install CLI - run: cargo binstall dioxus-cli -y --force --version 0.7.0-rc.0 + run: cargo binstall dioxus-cli -y --force --version 0.7.0-rc.1 - name: Build run: cd packages/docsite && dx build --verbose --trace --platform web --fullstack true --features fullstack,production --release --ssg - name: Generate search index diff --git a/Cargo.lock b/Cargo.lock index f94915b9dd..c70169cb0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "addr2line" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -511,21 +502,6 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "backtrace" -version = "0.3.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-link 0.2.1", -] - [[package]] name = "base16" version = "0.2.1" @@ -723,9 +699,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.40" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ "find-msvc-tools", "jobserver", @@ -825,9 +801,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2134bb3ea021b78629caa971416385309e0131b351b25e01dc16fb54e1b5fae" +checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" dependencies = [ "clap_builder", "clap_derive", @@ -835,9 +811,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.48" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ba64afa3c0a6df7fa517765e31314e983f51dda798ffba27b988194fb65dc9" +checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" dependencies = [ "anstream", "anstyle", @@ -847,9 +823,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -859,9 +835,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "client-ip" @@ -1012,7 +988,8 @@ dependencies = [ [[package]] name = "const-serialize" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62fa1b64a9432bd3ec5dfc7ed000b03a6bf2edb9e67bbe15e47c319506198c4c" dependencies = [ "const-serialize-macro", "serde", @@ -1021,7 +998,8 @@ dependencies = [ [[package]] name = "const-serialize-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "983992de580b235fff6a419247007b298cd2e7da0f11ee2491152cae49fa93f7" dependencies = [ "proc-macro2", "quote", @@ -1424,7 +1402,8 @@ dependencies = [ [[package]] name = "dioxus" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfab61caa2b10a905998c9cb5cb1717b8ce858f3cec009efb19fc91b159f2120" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -1436,15 +1415,15 @@ dependencies = [ "dioxus-document", "dioxus-fullstack", "dioxus-fullstack-macro", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-hooks", "dioxus-html", - "dioxus-liveview 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-liveview", "dioxus-logger", "dioxus-router", "dioxus-server", "dioxus-signals", - "dioxus-ssr 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-ssr", "dioxus-stores", "dioxus-web", "manganis", @@ -1456,7 +1435,8 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dcd9492970659cf77c1afcb79270ad62a3bf5ab1d90f12f565b26fd9ba2507" dependencies = [ "dioxus-cli-config", "http", @@ -1489,24 +1469,11 @@ dependencies = [ "syn 2.0.106", ] -[[package]] -name = "dioxus-autofmt" -version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-rsx", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "serde", - "syn 2.0.106", -] - [[package]] name = "dioxus-cli-config" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231a1a85b7977e938e55db0c9bd04893830e8ee72a5f0b610ce927939887718f" dependencies = [ "wasm-bindgen", ] @@ -1514,7 +1481,8 @@ dependencies = [ [[package]] name = "dioxus-config-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79022b079edb218464680678b6c9069f417f2185be021675be060e5c3be394d8" dependencies = [ "proc-macro2", "quote", @@ -1523,12 +1491,14 @@ dependencies = [ [[package]] name = "dioxus-config-macros" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee30f3e7b9faa3214de9e67e1ee39a4c1cccc600286cd31ad9f4b662d1bd62a4" [[package]] name = "dioxus-core" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cdb8ce8b66e981a0ce943184efa6dcdce06852f701642e0570648bec313596a" dependencies = [ "anyhow", "const_format", @@ -1550,7 +1520,8 @@ dependencies = [ [[package]] name = "dioxus-core-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf7bb96b7cd7bea18be827b720f35f15db8b493d1832e69277539eaf336897a" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", @@ -1562,12 +1533,14 @@ dependencies = [ [[package]] name = "dioxus-core-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f6ed5dc0c2fac63830b52c613be5380fc1d9e48981b65cd7a1771c725ba4b69" [[package]] name = "dioxus-desktop" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9417be8a0d0bfdcdecb0a28bd9728bfd23bcc24d2b1d624e0298d8cbd576a911" dependencies = [ "async-trait", "base64 0.22.1", @@ -1579,7 +1552,7 @@ dependencies = [ "dioxus-core", "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-hooks", "dioxus-html", "dioxus-interpreter-js", @@ -1621,7 +1594,8 @@ dependencies = [ [[package]] name = "dioxus-devtools" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee75595feb78aaf4101f95699b1323bbf7910ce5cfeec730725ec7781c88317" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -1641,7 +1615,8 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc965cdbe70c85e15e1d172546213dde0941afa2e1e0ff72510a5eea69db03e4" dependencies = [ "dioxus-core", "serde", @@ -1733,8 +1708,8 @@ dependencies = [ "dioxus", "dioxus-cli-config", "dioxus-desktop", - "dioxus-liveview 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-ssr 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-liveview", + "dioxus-ssr", "dioxus-web", "form_urlencoded", "futures", @@ -1765,7 +1740,8 @@ dependencies = [ [[package]] name = "dioxus-document" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "923edda3e26de60eb1954bf8bbe562dab891ee207f97bded3469b7b97ec27325" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -1783,7 +1759,8 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c63dba4f2f6e44cefbc8f6969abbe61fd497eaaa0447c365db853880d94d0a0" dependencies = [ "cargo_metadata", "manganis-core", @@ -1795,7 +1772,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f4bf3345e91a5c7fa27ada6c27722b2cdec39b6d58f55869d9bde7fce0204c8" dependencies = [ "anyhow", "async-stream", @@ -1859,7 +1837,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack-core" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e04f171276ca69d5d2266c786b390f281ed4c2b375db370d20d3eda0ebb5e891" dependencies = [ "anyhow", "axum-core 0.5.5", @@ -1867,7 +1846,7 @@ dependencies = [ "ciborium", "dioxus-core", "dioxus-document", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-hooks", "dioxus-signals", "futures-channel", @@ -1884,7 +1863,8 @@ dependencies = [ [[package]] name = "dioxus-fullstack-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d218f17463e0bf255599afe1ef477ca9049e549491032a57e618ee1bf65a6b17" dependencies = [ "const_format", "convert_case 0.8.0", @@ -1904,19 +1884,11 @@ dependencies = [ "tracing", ] -[[package]] -name = "dioxus-history" -version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "dioxus-core", - "tracing", -] - [[package]] name = "dioxus-hooks" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3843e73fb8f199326d9b77c2dce6c89dfd47f77cbd87dd50fedfb4a2f9fc8015" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1932,7 +1904,8 @@ dependencies = [ [[package]] name = "dioxus-html" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5341444c368b99d119646256292cb6b1034458f53280cff3b9dd9f5c992baab2" dependencies = [ "async-trait", "bytes", @@ -1959,7 +1932,8 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c19513628504ec7059812331d60e32d8d37b1f48c3252e5ad757db3e65b48c3" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -1970,7 +1944,8 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "352115c6688009b4319f5b510d7a438e67fa655394310a3706cffa7f6218b93e" dependencies = [ "dioxus-core", "dioxus-core-types", @@ -1997,34 +1972,7 @@ dependencies = [ "dioxus-core", "dioxus-devtools", "dioxus-document", - "dioxus-history 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", - "dioxus-html", - "dioxus-interpreter-js", - "futures-channel", - "futures-util", - "generational-box", - "rustc-hash 2.1.1", - "serde", - "serde_json", - "slab", - "thiserror 2.0.17", - "tokio", - "tokio-stream", - "tokio-util", - "tracing", -] - -[[package]] -name = "dioxus-liveview" -version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "axum 0.8.6", - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools", - "dioxus-document", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-html", "dioxus-interpreter-js", "futures-channel", @@ -2044,7 +1992,8 @@ dependencies = [ [[package]] name = "dioxus-logger" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567f266396a2bb65b13bbadd78241a70dfc8bd233aecc2b37f19237532c9ab21" dependencies = [ "dioxus-cli-config", "tracing", @@ -2059,7 +2008,7 @@ dependencies = [ "ansi-parser", "base64 0.22.1", "dioxus", - "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt", "dioxus-core", "dioxus-core-types", "dioxus-devtools", @@ -2093,7 +2042,7 @@ version = "0.0.1" source = "git+https://github.com/DioxusLabs/components#3571d90aa55773c59b05119d9fff8879da6b8a3d" dependencies = [ "dioxus", - "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=0.7)", + "dioxus-time", "lazy-js-bundle 0.6.2", "time", "tracing", @@ -2102,13 +2051,14 @@ dependencies = [ [[package]] name = "dioxus-router" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1ec9ea8a84b8b8eabae0f661e1926267b498d9a7265a31731d755b95abbe61" dependencies = [ "dioxus-cli-config", "dioxus-core", "dioxus-core-macro", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-hooks", "dioxus-html", "dioxus-router-macro", @@ -2122,7 +2072,8 @@ dependencies = [ [[package]] name = "dioxus-router-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6e8cb648e2146ba825c6a66c8b678f51a620d5f70852b7eb1c98b0e8286e8c" dependencies = [ "base16", "digest", @@ -2136,7 +2087,8 @@ dependencies = [ [[package]] name = "dioxus-rsx" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf7dfd6a789e69a5f952fbc8eeb1a8866014e0abee3882ebaceb139a4e12709a" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", @@ -2164,10 +2116,11 @@ dependencies = [ [[package]] name = "dioxus-rsx-rosetta" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51539cc91794445e60c897711047a6d64c5495aa797630181039b2b954e1279" dependencies = [ "convert_case 0.8.0", - "dioxus-autofmt 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-autofmt", "dioxus-html", "dioxus-rsx", "html_parser", @@ -2179,10 +2132,10 @@ dependencies = [ [[package]] name = "dioxus-sdk" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" +version = "0.7.0-rc.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" dependencies = [ - "dioxus-time 0.7.0-rc.0 (git+https://github.com/ealmloff/dioxus-std?branch=git)", + "dioxus-time", "dioxus-util", "dioxus-window", ] @@ -2233,7 +2186,8 @@ dependencies = [ [[package]] name = "dioxus-server" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac0a65350e056ee9b8116dca4f19ed16d290e5610f7593b3cabd756642020b4a" dependencies = [ "anyhow", "async-trait", @@ -2249,14 +2203,14 @@ dependencies = [ "dioxus-devtools", "dioxus-document", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-hooks", "dioxus-html", "dioxus-interpreter-js", "dioxus-logger", "dioxus-router", "dioxus-signals", - "dioxus-ssr 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-ssr", "enumset", "futures", "futures-channel", @@ -2290,7 +2244,8 @@ dependencies = [ [[package]] name = "dioxus-signals" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d1b204dc460bef2ff0c92e4044d58090fe5209fd93537dbb6f344fa379e835f" dependencies = [ "dioxus-core", "futures-channel", @@ -2314,21 +2269,11 @@ dependencies = [ "rustc-hash 2.1.1", ] -[[package]] -name = "dioxus-ssr" -version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" -dependencies = [ - "askama_escape 0.13.0", - "dioxus-core", - "dioxus-core-types", - "rustc-hash 2.1.1", -] - [[package]] name = "dioxus-stores" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560f16579c9a4c3fb81b41e6e5b9018e2e91b5c57d43469a37cf22807ca47acc" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2338,7 +2283,8 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf06d8e91f5af4b29e74a8ebaf7b6c778774e09a0f6551bf40409e263c781cdb" dependencies = [ "convert_case 0.8.0", "proc-macro2", @@ -2348,19 +2294,8 @@ dependencies = [ [[package]] name = "dioxus-time" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" -dependencies = [ - "dioxus", - "futures", - "gloo-timers", - "tokio", -] - -[[package]] -name = "dioxus-time" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" +version = "0.7.0-rc.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" dependencies = [ "dioxus", "futures", @@ -2370,8 +2305,8 @@ dependencies = [ [[package]] name = "dioxus-util" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" +version = "0.7.0-rc.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" dependencies = [ "dioxus", "serde", @@ -2380,7 +2315,8 @@ dependencies = [ [[package]] name = "dioxus-web" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824596741fc373f7b8600031016446c19d5e2f36a3bc0420e3b80466a2fd05c" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2388,7 +2324,7 @@ dependencies = [ "dioxus-devtools", "dioxus-document", "dioxus-fullstack-core", - "dioxus-history 0.7.0-rc.1 (git+https://github.com/dioxuslabs/dioxus)", + "dioxus-history", "dioxus-html", "dioxus-interpreter-js", "dioxus-signals", @@ -2412,8 +2348,8 @@ dependencies = [ [[package]] name = "dioxus-window" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=git#8baa37323dd6c4c60af915371132c5f086bd7933" +version = "0.7.0-rc.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" dependencies = [ "dioxus", "dioxus-config-macro", @@ -2834,9 +2770,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "flate2" @@ -3151,7 +3087,8 @@ dependencies = [ [[package]] name = "generational-box" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93e10f2f89a54e58670ad86e1896db4800b91af59ed55a2dc195d2ea5fecfa4" dependencies = [ "parking_lot", "tracing", @@ -3159,9 +3096,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -3234,12 +3171,6 @@ dependencies = [ "weezl", ] -[[package]] -name = "gimli" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" - [[package]] name = "gio" version = "0.18.4" @@ -3504,12 +3435,13 @@ dependencies = [ [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ] [[package]] @@ -3847,7 +3779,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.6.1", "system-configuration", "tokio", "tower-service", @@ -4122,17 +4054,6 @@ dependencies = [ "rustversion", ] -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - [[package]] name = "ipnet" version = "2.11.0" @@ -4294,7 +4215,8 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8697a8442f28425b7263aed3b2e25c94b273fb18f503b8bfb188865dfdcbb62b" [[package]] name = "lazy_static" @@ -4334,9 +4256,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.176" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libfuzzer-sys" @@ -4527,7 +4449,8 @@ dependencies = [ [[package]] name = "manganis" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d99d7bdf99077e989ef8b15195ac7b070f2274755560239b2ce9b15d5d3542" dependencies = [ "const-serialize", "manganis-core", @@ -4537,7 +4460,8 @@ dependencies = [ [[package]] name = "manganis-core" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05ca73545ec919930d103e66c1057f3a3dac273ac27db721a358546e7ce7aed" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -4548,7 +4472,8 @@ dependencies = [ [[package]] name = "manganis-macro" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#05f3b8d20f867733691553292ae73603c40a1a8a" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cc3b11e27e62b12f371afb4d703ea3ca119a6e48736fae0e5f0f5c9642e2879" dependencies = [ "dunce", "macro-string", @@ -4650,7 +4575,7 @@ version = "0.0.0" dependencies = [ "anyhow", "convert_case 0.6.0", - "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt", "dioxus-rsx", "macro_state", "mdbook-shared", @@ -4673,7 +4598,7 @@ name = "mdbook-gen-example" version = "0.0.0" dependencies = [ "dioxus", - "dioxus-autofmt 0.7.0-rc.1 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-autofmt", "mdbook-gen", "mdbook-shared", "prettyplease", @@ -4814,9 +4739,9 @@ dependencies = [ [[package]] name = "moxcms" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cc7d85f3d741164e8972ad355e26ac6e51b20fcae5f911c7da8f2d8bbbb3f33" +checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40" dependencies = [ "num-traits", "pxfm", @@ -4975,11 +4900,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -5185,15 +5110,6 @@ dependencies = [ "objc", ] -[[package]] -name = "object" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -5744,7 +5660,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.6", + "toml_edit 0.23.7", ] [[package]] @@ -5907,9 +5823,9 @@ dependencies = [ [[package]] name = "pxfm" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" dependencies = [ "num-traits", ] @@ -5975,7 +5891,7 @@ dependencies = [ "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.6.0", + "socket2 0.6.1", "thiserror 2.0.17", "tokio", "tracing", @@ -6012,7 +5928,7 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.0", + "socket2 0.6.1", "tracing", "windows-sys 0.60.2", ] @@ -6255,9 +6171,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.3" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -6267,9 +6183,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -6278,15 +6194,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", "bytes", @@ -6432,12 +6348,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -6991,12 +6901,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -7051,9 +6961,9 @@ checksum = "47df29f8d00075baa5eb3174fa870b43d7eacc7e95c22796f8c362f64e01f47c" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -7119,7 +7029,8 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3055f82c5a9f842a2a390a595a386343654a408790b3b20473c4b87a5c4ec3bf" dependencies = [ "js-sys", "libc", @@ -7137,7 +7048,8 @@ dependencies = [ [[package]] name = "subsecond-types" version = "0.7.0-rc.1" -source = "git+https://github.com/dioxuslabs/dioxus#76319005b851288ea096ab006fd73f0a71b9f2b8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61506acae0d5fc20d75943891ac9586e70cf7213c19fe0d0774e9d9648d4ee8" dependencies = [ "serde", ] @@ -7464,30 +7376,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", @@ -7609,9 +7518,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ "serde_core", ] @@ -7656,21 +7565,21 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.6" +version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ "indexmap 2.11.4", - "toml_datetime 0.7.2", + "toml_datetime 0.7.3", "toml_parser", "winnow 0.7.13", ] [[package]] name = "toml_parser" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ "winnow 0.7.13", ] @@ -7730,7 +7639,7 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project 1.1.10", - "socket2 0.6.0", + "socket2 0.6.1", "sync_wrapper", "tokio", "tokio-stream", @@ -9332,33 +9241,3 @@ dependencies = [ "syn 2.0.106", "winnow 0.7.13", ] - -[[patch.unused]] -name = "dioxus-geolocation" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" - -[[patch.unused]] -name = "dioxus-notification" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" - -[[patch.unused]] -name = "dioxus-sync" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" - -[[patch.unused]] -name = "dioxus-util" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" - -[[patch.unused]] -name = "dioxus-window" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" - -[[patch.unused]] -name = "dioxus_storage" -version = "0.7.0-rc.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5abb45906c47b4c864e1c06a3e6aebb1b5cae03c" diff --git a/Cargo.toml b/Cargo.toml index eae18262f7..732ecf6afa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,28 +63,28 @@ dioxus-search-macro = { path = "packages/search/search-macro" } dioxus-search-shared = { path = "packages/search/search-shared" } # Dioxus Release -dioxus = "0.7.0-rc.0" -dioxus-document = "0.7.0-rc.0" -dioxus-core = "0.7.0-rc.0" -dioxus-web = "0.7.0-rc.0" -dioxus-router = "0.7.0-rc.0" -dioxus-cli-config = "0.7.0-rc.0" -dioxus-desktop = "0.7.0-rc.0" -dioxus-liveview = "0.7.0-rc.0" -dioxus-ssr = "0.7.0-rc.0" -dioxus-core-types = "0.7.0-rc.0" -dioxus-devtools = "0.7.0-rc.0" -dioxus-rsx-hotreload = "0.7.0-rc.0" -dioxus-rsx = "0.7.0-rc.0" -dioxus-html = { version = "0.7.0-rc.0", default-features = false } -dioxus-rsx-rosetta = "0.7.0-rc.0" -dioxus-autofmt = "0.7.0-rc.0" -dioxus-dx-wire-format = "0.7.0-rc.0" -dioxus-devtools-types = { git = "https://github.com/DioxusLabs/dioxus" } -dioxus-logger = "0.7.0-rc.0" +dioxus = "0.7.0-rc.1" +dioxus-document = "0.7.0-rc.1" +dioxus-core = "0.7.0-rc.1" +dioxus-web = "0.7.0-rc.1" +dioxus-router = "0.7.0-rc.1" +dioxus-cli-config = "0.7.0-rc.1" +dioxus-desktop = "0.7.0-rc.1" +dioxus-liveview = "0.7.0-rc.1" +dioxus-ssr = "0.7.0-rc.1" +dioxus-core-types = "0.7.0-rc.1" +dioxus-devtools = "0.7.0-rc.1" +dioxus-rsx-hotreload = "0.7.0-rc.1" +dioxus-rsx = "0.7.0-rc.1" +dioxus-html = { version = "0.7.0-rc.1", default-features = false } +dioxus-rsx-rosetta = "0.7.0-rc.1" +dioxus-autofmt = "0.7.0-rc.1" +dioxus-dx-wire-format = "0.7.0-rc.1" +dioxus-devtools-types = "0.7.0-rc.1" +dioxus-logger = "0.7.0-rc.1" # 3rd-party dioxus -dioxus-sdk = { version = "0.7.0-rc.0", default-features = false } +dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } getrandom = { version = "0.2" } serde = { version = "1.0.215", features = ["derive"] } @@ -121,31 +121,3 @@ opt-level = 3 codegen-units = 1 -[patch.crates-io] -dioxus-geolocation = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-notification = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "git" } -dioxus_storage = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-sync = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-time = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-util = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } -dioxus-dx-wire-format = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-core = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-router = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-core-types = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-logger = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-cli-config = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-signals = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond = { git = "https://github.com/dioxuslabs/dioxus" } -subsecond-types = { git = "https://github.com/dioxuslabs/dioxus" } -generational-box = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-document = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-devtools = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-rsx = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-desktop = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-web = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-html = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-interpreter-js = { git = "https://github.com/dioxuslabs/dioxus" } -dioxus-rsx-rosetta = { git = "https://github.com/dioxuslabs/dioxus" } diff --git a/README.md b/README.md index 548db7a4fd..5f817cc9be 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ working `Rust` setup: ```sh -cargo binstall dioxus-cli@0.7.0-rc.0 --force --version 0.7.0-rc.0 +cargo binstall dioxus-cli@0.7.0-rc.1 --force --version 0.7.0-rc.1 ``` With [`dx`][dx] installed, you can use it to build and serve the documentation diff --git a/fly.toml b/fly.toml index f619502666..94214340a8 100644 --- a/fly.toml +++ b/fly.toml @@ -1,4 +1,4 @@ -# fly.toml app configuration file generated for docsite-playground-thrumming-sun-6870 on 2025-09-25T12:53:35-05:00 +# fly.toml app configuration file generated for docsite-playground on 2025-02-04T15:44:00-08:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index 6ff47b0a24..ade040678c 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -19,7 +19,7 @@ use tower_http::{compression::CompressionLayer, cors::CorsLayer}; mod app; mod build; -mod builtbuilt; +mod built; mod share; mod ws; @@ -64,8 +64,8 @@ async fn main() { // Build the routers. let built_router = Router::new() - .route("/", get(builtbuilt::serve_built_index)) - .route("/{*file_path}", get(builtbuilt::serve_other_built)); + .route("/", get(built::serve_built_index)) + .route("/{*file_path}", get(built::serve_other_built)); let shared_router = Router::new() .route("/", post(share_project)) From 85c6847ed3953b9f18cd40984e2841ac83436b40 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 10:21:04 -0500 Subject: [PATCH 43/58] more cleanup --- packages/playground/model/src/lib.rs | 7 + packages/playground/model/src/server.rs | 38 ++-- packages/playground/playground/assets/dxp.css | 150 --------------- packages/playground/playground/src/build.rs | 5 +- .../playground/src/editor/monaco.js | 2 +- packages/playground/playground/src/ws.rs | 6 +- packages/playground/server/src/app.rs | 13 +- .../playground/server/src/build/builder.rs | 174 +++++++++--------- .../playground/server/src/build/cleanup.rs | 13 +- .../playground/server/src/build/watcher.rs | 2 +- packages/playground/server/src/ws.rs | 7 +- 11 files changed, 147 insertions(+), 270 deletions(-) diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index 4dc40365a7..b6b29e815b 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -39,6 +39,12 @@ pub enum SocketMessage { AlreadyConnected, } +impl SocketMessage { + pub fn is_finished(&self) -> bool { + matches!(self, SocketMessage::BuildFinished(_)) + } +} + /// A stage of building from the playground. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum BuildStage { @@ -95,6 +101,7 @@ pub struct CargoDiagnosticSpan { pub column_start: usize, pub column_end: usize, pub label: Option, + pub file_name: String, } /// Any socket error. diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index d9d2c926a1..9441779bec 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -6,7 +6,7 @@ use crate::{ }; use axum::http::StatusCode; use axum::{extract::ws, response::IntoResponse}; -use dioxus_dx_wire_format::cargo_metadata::diagnostic::Diagnostic; +use dioxus_dx_wire_format::cargo_metadata::diagnostic::{Diagnostic, DiagnosticSpan}; use dioxus_dx_wire_format::{ cargo_metadata::{diagnostic::DiagnosticLevel, CompilerMessage}, BuildStage as DxBuildStage, @@ -69,15 +69,7 @@ impl TryFrom for CargoDiagnostic { let spans = diagnostic .spans .iter() - .filter(|s| s.file_name == "src/main.rs") - .map(|s| CargoDiagnosticSpan { - is_primary: s.is_primary, - line_start: s.line_start, - line_end: s.line_end, - column_start: s.column_start, - column_end: s.column_end, - label: s.label.clone(), - }) + .map(|s| s.clone().into()) .collect(); Ok(Self { @@ -103,15 +95,7 @@ impl TryFrom for CargoDiagnostic { let spans = value .spans .iter() - .filter(|s| s.file_name == "src/main.rs") - .map(|s| CargoDiagnosticSpan { - is_primary: s.is_primary, - line_start: s.line_start, - line_end: s.line_end, - column_start: s.column_start, - column_end: s.column_end, - label: s.label.clone(), - }) + .map(|s| s.clone().into()) .collect(); Ok(Self { @@ -124,6 +108,22 @@ impl TryFrom for CargoDiagnostic { } } + +impl From for CargoDiagnosticSpan{ + fn from(value: DiagnosticSpan) -> Self { + Self { + is_primary: value.is_primary, + line_start: value.line_start, + line_end: value.line_end, + column_start: value.column_start, + column_end: value.column_end, + label: value.label, + file_name: value.file_name, + } + } +} + + /// IntoResponse for app errors. impl IntoResponse for AppError { fn into_response(self) -> axum::response::Response { diff --git a/packages/playground/playground/assets/dxp.css b/packages/playground/playground/assets/dxp.css index 3f20b364d0..be2302366a 100644 --- a/packages/playground/playground/assets/dxp.css +++ b/packages/playground/playground/assets/dxp.css @@ -1,11 +1,9 @@ #dxp-playground-root { - border: 1px solid var(--dxp-border-light); overflow: hidden; } /* Header */ #dxp-header { - background-color: var(--dxp-bg-light-darker); display: flex; flex-direction: row; padding: 0.5rem; @@ -43,7 +41,6 @@ padding: 0px 10px; border-radius: 5px; border-style: none; - color: var(--dxp-text-light); font-family: "Inter", sans-serif; font-size: 14px; font-weight: 400; @@ -65,7 +62,6 @@ .dxp-ctrl-btn:hover { cursor: pointer; - background-color: var(--dxp-bg-light-lighter-alt); } #dxp-header-left > .dxp-ctrl-btn:not(:first-child) { @@ -88,18 +84,15 @@ margin-left: auto; margin-right: auto; display: flex; - border-left: 1px solid var(--dxp-border-light); } #dxp-panes-left { width: 50%; min-width: 100px; - background-color: var(--dxp-bg-light); } #dxp-panes-draggable { width: 12px; - background-color: var(--dxp-border-light); cursor: col-resize; user-select: none; display: flex; @@ -114,13 +107,11 @@ align-items: center; width: 50%; min-width: 100px; - background-color: var(--dxp-bg-light-darker); position: relative; overflow-y: scroll; } #dxp-panes-right > p { - color: var(--dxp-text-light); font-family: "Inter", sans-serif; user-select: none; text-align: center; @@ -169,7 +160,6 @@ } #dxp-panes-right > #dxp-progress-container > p { - color: var(--dxp-text-light); font-family: "Inter", sans-serif; margin-left: auto; margin-right: auto; @@ -182,7 +172,6 @@ width: 70%; margin-left: auto; margin-right: auto; - background-color: var(--dxp-bg-light-lighter); border-radius: 5px; overflow: hidden; } @@ -197,80 +186,7 @@ height: 100%; } -/* Modal */ -#dxp-modal-bg { - background-color: rgba(0, 0, 0, 40%); - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - z-index: 100; - - display: flex; - justify-content: center; - align-items: center; -} - -#dxp-modal { - background-color: var(--dxp-bg-light); - border: 1px solid #000000; - color: var(--dxp-text-light); - border-radius: 5px; - padding: 15px; - margin-bottom: 20vh; - - font-family: "Inter", sans-serif; - font-weight: 400; - - max-width: 500px; -} - -#dxp-modal-header { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; -} - -#dxp-modal-header > svg { - height: 40px; -} - -#dxp-modal-title { - font-size: 20px; - font-weight: 600; - margin-top: 0px; - margin-bottom: 0px; - margin-left: 10px; -} - -#dxp-modal-text { - font-weight: 400; - font-size: 16px; - margin-bottom: 20px; -} - -#dxp-modal-ok-btn { - display: block; - background-color: var(--dxp-bg-light-lighter); - border-radius: 3px; - color: var(--dxp-text-light); - padding: 8px; - - font-weight: 400; - font-size: 14px; - margin-left: auto; - - border: none; - transition: background-color 0.2s ease; -} - -#dxp-modal-ok-btn:hover { - background-color: var(--dxp-bg-light-darker); - cursor: pointer; -} /* Logs pane */ @@ -280,70 +196,4 @@ width: 100%; overflow-y: auto; } - -#logs .log { - padding: 20px 15px; - transition: background-color 0.3s ease; - color: var(--dxp-text-light); - border-bottom: var(--dxp-log-border) 1px solid; -} - -#logs .log:hover { - background-color: var(--dxp-bg-light); -} - -#logs .log .log-level { - font-family: "Inter", sans-serif; - padding-top: 0px; - padding-bottom: 10px; - margin: 0px; -} - -#logs .log .level-error { - color: var(--dxp-log-error-light); -} - -#logs .log .level-warn { - color: var(--dxp-log-warn-light); -} - -#logs .log .level-info { - color: var(--dxp-log-info-light); -} - -#logs .log .log-codeblock { - background-color: var(--dxp-bg-light); - padding: 10px; - border-radius: 10px; - border: var(--dxp-border-light) 1px solid; -} - -#logs .log .log-message, -#logs.log.log-span { - font-family: - ui-monospace, - SFMono-Regular, - SF Mono, - Menlo, - Consolas, - Liberation Mono, - monospace; -} - -#logs .log .log-message { - padding: 0px; - margin: 0px; -} - -#logs .log .log-span { - padding: 0px; - margin: 0px; - font-family: - ui-monospace, - SFMono-Regular, - SF Mono, - Menlo, - Consolas, - Liberation Mono, - monospace; } diff --git a/packages/playground/playground/src/build.rs b/packages/playground/playground/src/build.rs index b3b56e1346..58562e4725 100644 --- a/packages/playground/playground/src/build.rs +++ b/packages/playground/playground/src/build.rs @@ -127,8 +127,9 @@ pub async fn start_build( Err(e) => return Err(e), Ok(None) => break, Ok(Some(msg)) => { - let is_done = ws::handle_message(build, msg); - if is_done { + let finished = msg.is_finished(); + ws::handle_message(build, msg); + if finished { break; } } diff --git a/packages/playground/playground/src/editor/monaco.js b/packages/playground/playground/src/editor/monaco.js index 32349ed985..e5c47fd051 100644 --- a/packages/playground/playground/src/editor/monaco.js +++ b/packages/playground/playground/src/editor/monaco.js @@ -88,7 +88,7 @@ export function initMonaco( "semanticHighlighting.enabled": true, }); - // Super+Enter for Mac, Ctrl+Enter for others. + // Build on Ctrl+Enter / Cmd+Enter editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => { onBuildCallback(); }); diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index 53a716b5bf..cfebba0cf7 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -44,17 +44,15 @@ impl Socket { } /// Handles a websocket message, returning true if further messages shouldn't be handled. -pub fn handle_message(mut build: Store, message: SocketMessage) -> bool { +pub fn handle_message(mut build: Store, message: SocketMessage) { match message { SocketMessage::BuildStage(stage) => build.set_stage(BuildStage::Building(stage)), SocketMessage::QueuePosition(position) => build.set_stage(BuildStage::Queued(position)), SocketMessage::BuildFinished(BuildResult::Failed(failure)) => { build.set_stage(BuildStage::Finished(Err(failure))); - return true; } SocketMessage::BuildFinished(BuildResult::Built(id)) => { build.set_stage(BuildStage::Finished(Ok(id))); - return true; } SocketMessage::BuildFinished(BuildResult::HotPatched(patch)) => { // Get the iframe to apply the patch to. @@ -69,12 +67,10 @@ pub fn handle_message(mut build: Store, message: SocketMessage) -> b if let Some(id) = build.previous_build_id().cloned() { build.set_stage(BuildStage::Finished(Ok(id))); } - return true; } SocketMessage::BuildDiagnostic(diagnostic) => build.push_diagnostic(diagnostic), SocketMessage::RateLimited(time) => build.set_stage(BuildStage::Waiting(time)), _ => {} } - false } diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index c2da2e483e..962741ac5c 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -187,7 +187,7 @@ fn get_env_or(key: &str, default: F) -> F { #[derive(Clone)] pub struct AppState { /// The environment configuration. - pub env: EnvVars, + pub env: Arc, /// The time instante since the last request. pub last_request_time: Arc>, @@ -210,10 +210,6 @@ impl AppState { pub async fn new() -> Self { let mut env = EnvVars::new().await; - // Build the app state - let is_building = Arc::new(AtomicBool::new(false)); - let build_queue_tx = start_build_watcher(env.clone(), is_building.clone()); - // Get prebuild arg let prebuild = std::env::args().any(|x| x == "--prebuild"); @@ -222,6 +218,13 @@ impl AppState { env.shutdown_delay = Some(Duration::from_secs(1)); } + let env = Arc::new(env); + + // Build the app state + let is_building = Arc::new(AtomicBool::new(false)); + let build_queue_tx = start_build_watcher(env.clone(), is_building.clone()); + + let build_govener = Arc::new(RateLimiter::keyed( Quota::with_period(Duration::from_secs(5)) .expect("period is non-zero") diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index aa853acd43..45cc746e94 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -10,27 +10,27 @@ use model::{BuildStage, CargoDiagnostic}; use std::future::pending; use std::io::{BufRead, BufReader}; use std::path::Path; -use std::process::Stdio; use std::process::{Child, Command}; +use std::process::{ExitStatus, Stdio}; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use tokio::fs; use tokio::task::JoinHandle; use tracing::{trace, warn}; -const BUILD_ID_ID: &str = "{BUILD_ID}"; +const BUILD_ID_TEMPLATE: &str = "{BUILD_ID}"; -// TODO: We need some way of cleaning up any stopped builds. /// The builder provides a convenient interface for controlling builds running in another task. pub struct Builder { - env: EnvVars, + env: Arc, is_building: Arc, current_build: Option, task: Option, BuildError>>>, } impl Builder { - pub fn new(env: EnvVars, is_building: Arc) -> Self { + /// Create a new builder + pub fn new(env: Arc, is_building: Arc) -> Self { Self { env, is_building, @@ -39,8 +39,9 @@ impl Builder { } } - /// Make sure the components are initilized + /// Make sure the components are initialized pub fn update_component_library(&mut self) -> Result<(), BuildError> { + // Update the component library cache let update_status = Command::new("dx") .arg("component") .arg("update") @@ -51,6 +52,7 @@ impl Builder { if !update_status.success() { return Err(BuildError::DxFailed(update_status.code())); } + // Add all components to the template project let status = Command::new("dx") .arg("component") .arg("add") @@ -113,8 +115,8 @@ impl Builder { } } -/// Run the steps to produce a build for a [`BuildRequest`] -async fn build(env: EnvVars, request: BuildRequest) -> Result, BuildError> { +/// Run the steps to produce a build or patch for a [`BuildRequest`] +async fn build(env: Arc, request: BuildRequest) -> Result, BuildError> { let built_path = &env.built_path; let template_path = &env.build_template_path; @@ -129,7 +131,9 @@ async fn build(env: EnvVars, request: BuildRequest) -> Result, warn!("failed to clean built projects: {e}"); } - let patch = dx_build(&request, &env).await?; + // Build or hotpatch depending on the build state + let patch = dx_build(&request, env.clone()).await?; + // Move the built project or hotpatch binary into the built projects folder. move_to_built(&template_path, &built_path, &request, patch.is_some()).await?; Ok(patch) @@ -157,7 +161,7 @@ async fn setup_template( let new_path = &snippets_to_copy[i]; let contents = fs::read_to_string(path).await?; let contents = contents.replace( - BUILD_ID_ID, + BUILD_ID_TEMPLATE, &request .previous_build_id .filter(|_| patch) @@ -179,6 +183,8 @@ async fn setup_template( /// Start a process with limited access to the environment and resources fn start_limited_process(mut command: Command, env: &EnvVars) -> Result { + // We want to limit the environment variables passed to dx to only those needed for Rust. + // This prevents leaking any sensitive information to the build process which could be read with env! let filtered_vars = std::env::vars().filter(|(k, _)| { let allowed = ["RUST_VERSION", "RUSTUP_HOME", "CARGO_HOME", "PATH", "HOME"]; allowed.contains(&k.as_str()) @@ -200,16 +206,17 @@ fn start_limited_process(mut command: Command, env: &EnvVars) -> Result Result, BuildError> { +async fn dx_build(request: &BuildRequest, env: Arc) -> Result, BuildError> { + // If there is a previous build, get the cache dir for that build if it exists let previous_build_cache_dir = request .previous_build_id .map(|id| env.built_template_hotpatch_cache(&id)) .filter(|p| p.exists()); - // if there is a previous cache, try to use that to hot patch the build + // Ff there is a previous cache, try to use that to hot patch the build if let Some(cache_dir) = previous_build_cache_dir { let cache_dir = cache_dir.canonicalize()?; - let result = dx_patch_build(&request, &env, &cache_dir).await; + let result = start_dx_build(&request, env.clone(), &cache_dir, true).await; if let Ok(Some(patch)) = result { return Ok(Some(patch)); } else { @@ -217,6 +224,7 @@ async fn dx_build(request: &BuildRequest, env: &EnvVars) -> Result Result, cache_dir: &Path, + patch: bool, ) -> Result, BuildError> { - setup_template(&env.build_template_path, &request, true).await?; + setup_template(&env.build_template_path, &request, patch).await?; let mut command = Command::new("dx"); - command - .arg("tools") - .arg("hotpatch") - .arg("--web") - .arg("--session-cache-dir") - .arg(cache_dir) - .arg("--aslr-reference") - .arg("0") - .arg("--json-output"); + if patch { + // If we are patching, use the hotpatch tool instead of doing a full build + command + .arg("tools") + .arg("hotpatch") + .arg("--web") + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("--aslr-reference") + .arg("0") + .arg("--json-output"); + } else { + command + .arg("build") + .arg("--web") + // We always do a fat binary build to allow hotpatching later. + .arg("--fat-binary") + // Each build gets its own session dir we re-use later for hotpatching. + .arg("--session-cache-dir") + .arg(cache_dir) + .arg("--json-output"); + } tracing::info!("running dx command: {:?}", command); - let mut child = start_limited_process(command, env)?; + let mut child = start_limited_process(command, &env)?; - // If there is a artifacts cache, we can pipe it to dx for hot patching. - let artifacts_cache = cache_dir.join("artifacts.json"); - let artifacts_cache = std::fs::read_to_string(artifacts_cache)?; - if let Some(mut stdin) = child.stdin.take() { - use std::io::Write; - stdin.write_all(artifacts_cache.as_bytes())?; - stdin.flush()?; + if patch { + // If there is a artifacts cache, we can pipe it to dx for hot patching. + let artifacts_cache = cache_dir.join("artifacts.json"); + let artifacts_cache = std::fs::read_to_string(artifacts_cache)?; + if let Some(mut stdin) = child.stdin.take() { + use std::io::Write; + stdin.write_all(artifacts_cache.as_bytes())?; + stdin.flush()?; + } } - let (logs, patch) = process_build_messages(&mut child, env, request); - - let status = tokio::task::spawn_blocking(move || child.wait()).await; + let BuildResult { logs, patch, status } = tokio::task::spawn_blocking({ + let request = request.clone(); + move || { + process_build_messages(&mut child, &env, &request) + }}) + .await?; // Check if the build was successful. - let exit_code = status.map(|r| r.map(|c| c.code())); - if let Ok(Ok(Some(code))) = exit_code { + if let Ok(Some(code)) = status.as_ref().map(ExitStatus::code) { if code == 0 { return Ok(patch); } else { @@ -282,49 +308,18 @@ async fn dx_patch_build( Err(BuildError::DxFailed(None)) } -async fn dx_full_build( - request: &BuildRequest, - env: &EnvVars, - cache_dir: &Path, -) -> Result<(), BuildError> { - setup_template(&env.build_template_path, &request, false).await?; - - let mut command = Command::new("dx"); - command - .arg("build") - .arg("--web") - .arg("--fat-binary") - .arg("--session-cache-dir") - .arg(cache_dir) - .arg("--json-output"); - tracing::info!("running dx command: {:?}", command); - let mut child = start_limited_process(command, env)?; - - let (logs, _patch) = process_build_messages(&mut child, env, request); - - let status = tokio::task::spawn_blocking(move || child.wait()).await; - - // Check if the build was successful. - let exit_code = status.map(|r| r.map(|c| c.code())); - if let Ok(Ok(Some(code))) = exit_code { - if code == 0 { - return Ok(()); - } else { - // Dump logs in debug. - for log in logs { - debug!("{log}"); - } - return Err(BuildError::DxFailed(Some(code))); - } - } - Err(BuildError::DxFailed(None)) +struct BuildResult { + logs: Vec, + patch: Option, + status: std::io::Result, } +/// Process the stdout and stderr of a dx build process, returning the logs and any hotpatch jump table fn process_build_messages( child: &mut Child, env: &EnvVars, request: &BuildRequest, -) -> (Vec, Option) { +) -> BuildResult { let stderr = child.stderr.take().expect("dx stdout should exist"); let stdout = child.stdout.take().expect("dx stdout should exist"); let mut stdout_reader = BufReader::new(stdout).lines(); @@ -343,12 +338,14 @@ fn process_build_messages( warn!("dx stderr: {line}"); } - (logs, patch) + let status = child.wait(); + + BuildResult { logs, patch, status } } +/// Limit a child process's resource usage. This prevents extremely long builds or excessive memory usage from crashing the server. #[allow(unused)] fn set_dx_limits(process: &Child, env: &EnvVars) { - // TODO this isn't working, not sure why #[cfg(any(target_os = "android", target_os = "linux"))] { use rustix::process::{Resource, Rlimit}; @@ -373,7 +370,7 @@ fn set_dx_limits(process: &Child, env: &EnvVars) { } } -/// Process a JSON-formatted message from the DX CLI, returning nothing on error. +/// Process a JSON-formatted message from the DX CLI, returning a JumpTable if a hot-patch was produced. /// /// We don't care if this errors as it is human-readable output which the playground doesn't depend on for build status. fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> Option { @@ -385,7 +382,16 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> return None; }; - let _ = match output { + let from_main_crate = |diagnostic: &CargoDiagnostic| { + // Only send diagnostic for the main.rs file of the current build + diagnostic.target_crate == Some(format!("play-{}", request.id)) + && diagnostic + .spans + .iter() + .any(|s| s.file_name == "src/main.rs") + }; + + _ = match output { StructuredOutput::BuildUpdate { stage } => { let stage = BuildStage::from(stage); request.ws_msg_tx.send(BuildMessage::Building(stage)) @@ -395,8 +401,7 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> return None; }; - // Don't send any diagnostics for dependencies. - if diagnostic.target_crate != Some(format!("play-{}", request.id)) { + if !from_main_crate(&diagnostic) { return None; } @@ -409,6 +414,10 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> return None; }; + if !from_main_crate(&diagnostic) { + return None; + } + request .ws_msg_tx .send(BuildMessage::CargoDiagnostic(diagnostic)) @@ -422,6 +431,7 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> ) { warn!("failed to write artifacts cache {artifacts_cache:?}: {err}"); } + Ok(()) } StructuredOutput::Hotpatch { jump_table, .. } => { diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index d90161e17b..c47e3fe967 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -9,9 +9,12 @@ pub async fn check_cleanup(env: &EnvVars) -> Result<(), io::Error> { Ok(()) } -/// Check and cleanup the target dir if it exceeds the max size. +/// Check and cleanup the target dir if it exceeds the max size. The hot reloading +/// cache is inside the target dir so it will also be cleared when the incremental +/// artifacts are removed. async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { let target_path = env.target_dir(); + // If we just cleaned or this is the first run, the target dir may not exist. if !target_path.exists() { return Ok(()); } @@ -25,8 +28,10 @@ async fn check_target_cleanup(env: &EnvVars) -> Result<(), io::Error> { Ok(()) } -/// Check and cleanup any expired built projects +/// Check and cleanup any expired built projects. This tends to be much smaller +/// than the target dir, but it can grow large over time as patches accumulate. async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { + // If we just cleaned or this is the first run, the built dir may not exist. if !env.built_path.exists() { return Ok(()); } @@ -34,6 +39,7 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { let mut dir = tokio::fs::read_dir(&env.built_path).await?; let mut dirs_with_size = Vec::new(); + // Go through the project directory and find the size and time modified for each project dir. while let Some(item) = dir.next_entry().await? { let path = item.path(); let Some(filename) = path.file_name() else { @@ -57,9 +63,11 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { let total_size: u64 = dirs_with_size.iter().map(|(_, _, _, size)| *size).sum(); // If it exceeds the max, sort by oldest and remove until under the limit. if total_size > env.max_built_dir_size { + // Sort by oldest first dirs_with_size.sort_by_key(|(_, _, time_elapsed, _)| *time_elapsed); let mut size = total_size; + // Remove oldest dirs until under the max size. for (pathname, item, _, dir_size) in dirs_with_size { if size <= env.max_built_dir_size { break; @@ -97,6 +105,7 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { Ok(()) } +/// Recursively calculate the size of a directory. async fn dir_size(path: &std::path::Path) -> Result { let mut size = 0; let mut dirs = vec![path.to_path_buf()]; diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index ef828cf968..7042c32d94 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -17,7 +17,7 @@ use uuid::Uuid; /// The build watcher receives [`BuildCommand`]s through a channel and handles /// the build queue, providing queue positions, and stopping/cancelling builds. pub fn start_build_watcher( - env: EnvVars, + env: Arc, is_building: Arc, ) -> UnboundedSender { let (tx, mut rx) = mpsc::unbounded_channel(); diff --git a/packages/playground/server/src/ws.rs b/packages/playground/server/src/ws.rs index d80983e4dd..c5d21e6de0 100644 --- a/packages/playground/server/src/ws.rs +++ b/packages/playground/server/src/ws.rs @@ -52,7 +52,8 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { // Start a new build if let SocketMessage::BuildRequest { code, previous_build_id } = socket_msg { - // Rate limit the build requests by ip + // Rate limit the build requests by ip. If we are being rate limited, send a message + // to the client with the wait time and then wait before continuing. if let Err(n) = state.build_govener.check_key(&ip) { let wait_time = n.wait_time_from(QuantaClock::default().now()); let socket_msg = SocketMessage::RateLimited(wait_time); @@ -76,8 +77,8 @@ async fn handle_socket(state: AppState, ip: IpAddr, socket: WebSocket) { break; } - // If the build finished, let's close this socket. - if build_msg.is_done() { + // If the build finished, close this socket. + if build_msg.is_done() { current_build = None; let _ = socket_tx.close().await; break; From 931f3428a8b2135ad36d50666e539f3c76ee1425 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 10:22:33 -0500 Subject: [PATCH 44/58] fix clippy warnings in the playground --- packages/playground/model/src/lib.rs | 6 ------ packages/playground/model/src/project.rs | 2 +- packages/playground/model/src/server.rs | 2 +- packages/playground/server/src/app.rs | 2 +- packages/playground/server/src/build/builder.rs | 6 +++--- packages/playground/server/src/build/cleanup.rs | 5 ++--- packages/playground/server/src/build/watcher.rs | 5 ++--- 7 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index b6b29e815b..9a8f7edcdf 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -71,12 +71,6 @@ impl TryFrom for SocketMessage { } } -impl SocketMessage { - pub(crate) fn from_bytes>(value: B) -> Result { - Ok(serde_json::from_slice(value.as_ref())?) - } -} - /// A cargo diagnostic #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)] pub struct CargoDiagnostic { diff --git a/packages/playground/model/src/project.rs b/packages/playground/model/src/project.rs index ee7733c446..754969335c 100644 --- a/packages/playground/model/src/project.rs +++ b/packages/playground/model/src/project.rs @@ -84,7 +84,7 @@ impl Project { // If the project has already been shared, return the share code. // We remove the shared id if the content changes. if let Some(share_code) = &shared_id { - return Ok(share_code.clone()); + return Ok(*share_code); } let url = format!("{}/shared", client.server_url); diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 9441779bec..81b8155b99 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -46,7 +46,7 @@ impl TryFrom for SocketMessage { fn try_from(value: ws::Message) -> Result { let text = value.into_data(); - SocketMessage::from_bytes(text) + Ok(serde_json::from_slice(&text)?) } } diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 962741ac5c..8a7c8956ce 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -33,7 +33,7 @@ const DEFAULT_PORT: u16 = 3000; const DEFAULT_BUILD_TEMPLATE_PATH: &str = "./template"; /// Max size of the built directory before old projects are removed. -const DEFAULT_BUILT_DIR_SIZE: u64 = 1 * 1024 * 1024 * 1024; // 1 GB +const DEFAULT_BUILT_DIR_SIZE: u64 = 1024 * 1024 * 1024; // 1 GB /// Max memory usage of dx during a build before it is killed. const DEFAULT_DX_MEMORY_LIMIT: u64 = 5 * 1024 * 1024 * 1024; // 5 GB /// Max seconds a dx build can take before it is killed. diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 45cc746e94..6da0361b5a 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -134,7 +134,7 @@ async fn build(env: Arc, request: BuildRequest) -> Result) -> Result Result, BuildError> { - setup_template(&env.build_template_path, &request, patch).await?; + setup_template(&env.build_template_path, request, patch).await?; let mut command = Command::new("dx"); if patch { // If we are patching, use the hotpatch tool instead of doing a full build diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index c47e3fe967..9f629797d6 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -85,14 +85,13 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { let mut wasm_dir = tokio::fs::read_dir(&wasm_path).await?; while let Some(entry) = wasm_dir.next_entry().await? { let entry_path = entry.path(); - if let Some(name) = entry_path.file_name() { - if name.to_string_lossy().contains("patch") { + if let Some(name) = entry_path.file_name() + && name.to_string_lossy().contains("patch") { let patch_size = entry.metadata().await.map(|m| m.len()).unwrap_or(0); _ = tokio::fs::remove_file(&entry_path).await; size -= patch_size; } - } } } } else { diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index 7042c32d94..5443e2d805 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -74,8 +74,8 @@ fn start_build( fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque, id: Uuid) { // Check if the ongoing build is the cancelled build. let current_build_id = builder.current_build().map(|b| b.id); - if let Some(current_build_id) = current_build_id { - if id == current_build_id { + if let Some(current_build_id) = current_build_id + && id == current_build_id { builder.stop_current(); // Start the next build request. @@ -87,7 +87,6 @@ fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque update_queue_positions(pending_builds); return; } - } // Try finding the build in the queue let mut matching_id = None; From 61e45e4e7e8283e96cd7c013aca97afebbe5dbe0 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 10:26:45 -0500 Subject: [PATCH 45/58] fix remaining clippy issues --- .../src/doc_examples/__interactive_04.rs | 2 +- .../src/doc_examples/asynchronous.rs | 8 +++--- .../src/doc_examples/component_lifecycle.rs | 4 +-- .../src/doc_examples/data_fetching.rs | 28 ++++++++----------- .../src/doc_examples/error_handling.rs | 2 +- .../src/doc_examples/hackernews_async.rs | 4 +-- .../src/doc_examples/hackernews_complete.rs | 2 +- .../src/doc_examples/hackernews_post.rs | 4 +-- .../src/doc_examples/hackernews_state.rs | 6 ++-- .../src/doc_examples/reactivity.rs | 6 ++-- packages/docs-router/src/lib.rs | 6 ++-- .../packages/mdbook-gen-example/build.rs | 1 - .../packages/mdbook-gen/src/lib.rs | 21 +------------- .../packages/mdbook-shared/src/query.rs | 3 +- .../packages/mdbook-shared/src/summary.rs | 2 +- packages/notion-to-blog/src/main.rs | 9 ++---- packages/search/search-macro/src/lib.rs | 4 +-- packages/search/search-shared/src/lib.rs | 2 +- 18 files changed, 43 insertions(+), 71 deletions(-) diff --git a/packages/docs-router/src/doc_examples/__interactive_04.rs b/packages/docs-router/src/doc_examples/__interactive_04.rs index 8d986e2583..af25a3cd07 100644 --- a/packages/docs-router/src/doc_examples/__interactive_04.rs +++ b/packages/docs-router/src/doc_examples/__interactive_04.rs @@ -25,7 +25,7 @@ pub fn component_borrowed_props() -> Element { } pub fn hooks_use_ref() -> Element { - let mut list = use_signal(|| Vec::new()); + let mut list = use_signal(Vec::new); rsx! { p { "Current list: {list:?}" } diff --git a/packages/docs-router/src/doc_examples/asynchronous.rs b/packages/docs-router/src/doc_examples/asynchronous.rs index c1737d2f9c..d2aa057ce8 100644 --- a/packages/docs-router/src/doc_examples/asynchronous.rs +++ b/packages/docs-router/src/doc_examples/asynchronous.rs @@ -191,7 +191,7 @@ pub fn UseResource() -> Element { pub fn NotCancelSafe() -> Element { // ANCHOR: not_cancel_safe - static RESOURCES_RUNNING: GlobalSignal> = Signal::global(|| HashSet::new()); + static RESOURCES_RUNNING: GlobalSignal> = Signal::global(HashSet::new); let mut breed = use_signal(|| "hound".to_string()); let dogs = use_resource(move || async move { // Modify some global state @@ -258,7 +258,7 @@ pub fn NotCancelSafe() -> Element { pub fn CancelSafe() -> Element { // ANCHOR: cancel_safe - static RESOURCES_RUNNING: GlobalSignal> = Signal::global(|| HashSet::new()); + static RESOURCES_RUNNING: GlobalSignal> = Signal::global(HashSet::new); let mut breed = use_signal(|| "hound".to_string()); let dogs = use_resource(move || async move { // Modify some global state @@ -433,7 +433,7 @@ mod suspense_boundary { } #[component] - fn BreedGallery(breed: ReadOnlySignal) -> Element { + fn BreedGallery(breed: ReadSignal) -> Element { let response = use_resource(move || async move { // Artificially slow down the request to make the loading indicator easier to seer gloo_timers::future::TimeoutFuture::new(1000).await; @@ -521,7 +521,7 @@ mod use_server_future { // ANCHOR: use_server_future #[component] - fn BreedGallery(breed: ReadOnlySignal) -> Element { + fn BreedGallery(breed: ReadSignal) -> Element { // use_server_future is very similar to use_resource, but the value returned from the future // must implement Serialize and Deserialize and it is automatically suspended let response = use_server_future(move || async move { diff --git a/packages/docs-router/src/doc_examples/component_lifecycle.rs b/packages/docs-router/src/doc_examples/component_lifecycle.rs index 33966cd7d6..09e8071f86 100644 --- a/packages/docs-router/src/doc_examples/component_lifecycle.rs +++ b/packages/docs-router/src/doc_examples/component_lifecycle.rs @@ -101,9 +101,7 @@ mod effect { // You can use them to read or modify the rendered component use_effect(|| { log!("Effect ran"); - document::eval(&format!( - "document.getElementById('effect-output').innerText = 'Effect ran'" - )); + document::eval("document.getElementById('effect-output').innerText = 'Effect ran'"); }); rsx! { diff --git a/packages/docs-router/src/doc_examples/data_fetching.rs b/packages/docs-router/src/doc_examples/data_fetching.rs index 0f0e115bdd..436300895f 100644 --- a/packages/docs-router/src/doc_examples/data_fetching.rs +++ b/packages/docs-router/src/doc_examples/data_fetching.rs @@ -9,14 +9,12 @@ mod waterfall_effect { } // ANCHOR: waterfall_effect - fn fetch_dog_image(breed: impl Display) -> impl Future> { - async move { - let response = reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) - .await? - .json::() - .await?; - dioxus::Ok(response.message) - } + async fn fetch_dog_image(breed: impl Display) -> dioxus::Result { + let response = reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) + .await? + .json::() + .await?; + dioxus::Ok(response.message) } #[component] @@ -79,14 +77,12 @@ mod no_waterfall_effect { message: String, } - fn fetch_dog_image(breed: impl Display) -> impl Future> { - async move { - let response = reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) - .await? - .json::() - .await?; - dioxus::Ok(response.message) - } + async fn fetch_dog_image(breed: impl Display) -> dioxus::Result { + let response = reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) + .await? + .json::() + .await?; + dioxus::Ok(response.message) } #[component] diff --git a/packages/docs-router/src/doc_examples/error_handling.rs b/packages/docs-router/src/doc_examples/error_handling.rs index fedc99fb42..c17696441e 100644 --- a/packages/docs-router/src/doc_examples/error_handling.rs +++ b/packages/docs-router/src/doc_examples/error_handling.rs @@ -141,7 +141,7 @@ mod phone_number_validation { // ANCHOR: phone_number_validation #[component] pub fn PhoneNumberValidation() -> Element { - let mut phone_number = use_signal(|| String::new()); + let mut phone_number = use_signal(String::new); let parsed_phone_number = use_memo(move || phone_number().parse::()); rsx! { diff --git a/packages/docs-router/src/doc_examples/hackernews_async.rs b/packages/docs-router/src/doc_examples/hackernews_async.rs index 896ec12067..fd9009aedd 100644 --- a/packages/docs-router/src/doc_examples/hackernews_async.rs +++ b/packages/docs-router/src/doc_examples/hackernews_async.rs @@ -129,7 +129,7 @@ pub mod fetch { } #[component] - fn StoryListing(story: ReadOnlySignal) -> Element { + fn StoryListing(story: ReadSignal) -> Element { let mut preview_state = consume_context::>(); let StoryItem { title, @@ -297,7 +297,7 @@ async fn resolve_story( } #[component] -fn StoryListing(story: ReadOnlySignal) -> Element { +fn StoryListing(story: ReadSignal) -> Element { let mut preview_state = consume_context::>(); let StoryItem { title, diff --git a/packages/docs-router/src/doc_examples/hackernews_complete.rs b/packages/docs-router/src/doc_examples/hackernews_complete.rs index 7e4bd7d69d..a1be7153d7 100644 --- a/packages/docs-router/src/doc_examples/hackernews_complete.rs +++ b/packages/docs-router/src/doc_examples/hackernews_complete.rs @@ -50,7 +50,7 @@ async fn resolve_story( } #[component] -fn StoryListing(story: ReadOnlySignal) -> Element { +fn StoryListing(story: ReadSignal) -> Element { let preview_state = consume_context::>(); let StoryItem { title, diff --git a/packages/docs-router/src/doc_examples/hackernews_post.rs b/packages/docs-router/src/doc_examples/hackernews_post.rs index 08964291f7..b79ab2ff5f 100644 --- a/packages/docs-router/src/doc_examples/hackernews_post.rs +++ b/packages/docs-router/src/doc_examples/hackernews_post.rs @@ -170,7 +170,7 @@ pub mod story_v6 { } #[component] - fn StoryListing(story: ReadOnlySignal) -> Element { + fn StoryListing(story: ReadSignal) -> Element { let StoryItem { title, url, @@ -268,7 +268,7 @@ pub mod story_final { } #[component] - fn StoryListing(story: ReadOnlySignal) -> Element { + fn StoryListing(story: ReadSignal) -> Element { let StoryItem { title, url, diff --git a/packages/docs-router/src/doc_examples/hackernews_state.rs b/packages/docs-router/src/doc_examples/hackernews_state.rs index b5725c45ed..1d1fa7ae10 100644 --- a/packages/docs-router/src/doc_examples/hackernews_state.rs +++ b/packages/docs-router/src/doc_examples/hackernews_state.rs @@ -79,7 +79,7 @@ pub mod app_v1 { // ANCHOR_END: app_v1 #[component] - fn StoryListing(story: ReadOnlySignal) -> Element { + fn StoryListing(story: ReadSignal) -> Element { let StoryItem { title, url, @@ -190,7 +190,7 @@ mod story_listing_listener { } #[component] - fn StoryListing(story: ReadOnlySignal) -> Element { + fn StoryListing(story: ReadSignal) -> Element { let mut preview_state = consume_context::>(); let StoryItem { title, @@ -260,7 +260,7 @@ pub fn App() -> Element { // ANCHOR: shared_state_stories #[component] -fn StoryListing(story: ReadOnlySignal) -> Element { +fn StoryListing(story: ReadSignal) -> Element { let mut preview_state = consume_context::>(); let StoryItem { title, diff --git a/packages/docs-router/src/doc_examples/reactivity.rs b/packages/docs-router/src/doc_examples/reactivity.rs index 9bf04c61b8..3d36f883bd 100644 --- a/packages/docs-router/src/doc_examples/reactivity.rs +++ b/packages/docs-router/src/doc_examples/reactivity.rs @@ -348,11 +348,11 @@ mod non_reactive_state { use super::*; // ANCHOR: making_props_reactive - // You can track props by wrapping the type in a ReadOnlySignal - // Dioxus will automatically convert T into ReadOnlySignal when you pass + // You can track props by wrapping the type in a ReadSignal + // Dioxus will automatically convert T into ReadSignal when you pass // props to the component #[component] - fn Count(count: ReadOnlySignal) -> Element { + fn Count(count: ReadSignal) -> Element { // Then when you read count inside the memo, it subscribes to the count signal let double_count = use_memo(move || count() * 2); diff --git a/packages/docs-router/src/lib.rs b/packages/docs-router/src/lib.rs index c683162e78..c96da597b7 100644 --- a/packages/docs-router/src/lib.rs +++ b/packages/docs-router/src/lib.rs @@ -97,6 +97,7 @@ pub fn DemoFrame( } } +#[component] pub fn LayoutsExplanation() -> Element { rsx! { pre { onmouseenter: move |_| {}, onmouseleave: move |_| {}, @@ -157,7 +158,8 @@ pub fn CodeBlock(contents: String, name: Option) -> Element { } } -pub(crate) static Copy: Component<()> = |_| { +#[component] +pub(crate) fn Copy() -> Element { rsx!( svg { width: "24", @@ -168,4 +170,4 @@ pub(crate) static Copy: Component<()> = |_| { path { d: "M8 16c0 1.886 0 2.828.586 3.414C9.172 20 10.114 20 12 20h4c1.886 0 2.828 0 3.414-.586C20 18.828 20 17.886 20 16v-4c0-1.886 0-2.828-.586-3.414C18.828 8 17.886 8 16 8m-8 8h4c1.886 0 2.828 0 3.414-.586C16 14.828 16 13.886 16 12V8m-8 8c-1.886 0-2.828 0-3.414-.586C4 14.828 4 13.886 4 12V8c0-1.886 0-2.828.586-3.414C5.172 4 6.114 4 8 4h4c1.886 0 2.828 0 3.414.586C16 5.172 16 6.114 16 8" } } ) -}; +} diff --git a/packages/include_mdbook/packages/mdbook-gen-example/build.rs b/packages/include_mdbook/packages/mdbook-gen-example/build.rs index eead20d545..7c21db693f 100644 --- a/packages/include_mdbook/packages/mdbook-gen-example/build.rs +++ b/packages/include_mdbook/packages/mdbook-gen-example/build.rs @@ -1,4 +1,3 @@ -use std::{env::current_dir, path::PathBuf}; fn main() { // // re-run only if the "example-book" directory changes diff --git a/packages/include_mdbook/packages/mdbook-gen/src/lib.rs b/packages/include_mdbook/packages/mdbook-gen/src/lib.rs index c92496cb0c..f73311d8a5 100644 --- a/packages/include_mdbook/packages/mdbook-gen/src/lib.rs +++ b/packages/include_mdbook/packages/mdbook-gen/src/lib.rs @@ -8,7 +8,6 @@ use mdbook_shared::MdBook; use proc_macro2::Ident; use proc_macro2::Span; use proc_macro2::TokenStream as TokenStream2; -use quote::format_ident; use quote::quote; use quote::ToTokens; use syn::LitStr; @@ -24,8 +23,7 @@ pub fn make_docs_from_ws(version: &str) { let mut out = generate_router_build_script(mdbook_dir); out.push_str("use dioxus_docs_examples::*;\n"); out.push_str("use dioxus::prelude::*;\n"); - let version_flattened = version.replace(".", ""); - let filename = format!("docsgen.rs"); + let filename = "docsgen.rs".to_string(); std::fs::write(out_dir.join(filename), out).unwrap(); } @@ -330,20 +328,3 @@ pub(crate) fn path_to_route_enum_with_section( } }) } - -fn rustfmt_via_cli(input: &str) -> String { - let tmpfile = std::env::temp_dir().join(format!("mdbook-gen-{}.rs", std::process::id())); - std::fs::write(&tmpfile, input).unwrap(); - - let file = std::fs::File::open(&tmpfile).unwrap(); - let output = std::process::Command::new("rustfmt") - .arg("--edition=2021") - .stdin(file) - .stdout(std::process::Stdio::piped()) - .output() - .unwrap(); - - _ = std::fs::remove_file(tmpfile); - - String::from_utf8(output.stdout).unwrap() -} diff --git a/packages/include_mdbook/packages/mdbook-shared/src/query.rs b/packages/include_mdbook/packages/mdbook-shared/src/query.rs index 936e6bd413..480bd45f96 100644 --- a/packages/include_mdbook/packages/mdbook-shared/src/query.rs +++ b/packages/include_mdbook/packages/mdbook-shared/src/query.rs @@ -194,8 +194,7 @@ impl MdBook { c.is_ascii_alphanumeric() || *c == ' ' || *c == '-' || *c == '_' }) .collect::() - .replace('_', "-") - .replace(' ', "-"); + .replace(['_', ' '], "-"); sections.push(Section { level: *current_level as usize, title: title.clone(), diff --git a/packages/include_mdbook/packages/mdbook-shared/src/summary.rs b/packages/include_mdbook/packages/mdbook-shared/src/summary.rs index a49132603e..1cb47652c3 100644 --- a/packages/include_mdbook/packages/mdbook-shared/src/summary.rs +++ b/packages/include_mdbook/packages/mdbook-shared/src/summary.rs @@ -245,7 +245,7 @@ impl<'a> SummaryParser<'a> { /// Get the current line and column to give the user more useful error /// messages. fn current_location(&self) -> (usize, usize) { - let previous_text = self.src[..self.offset].as_bytes(); + let previous_text = &self.src.as_bytes()[..self.offset]; let line = Memchr::new(b'\n', previous_text).count() + 1; let start_of_line = memchr::memrchr(b'\n', previous_text).unwrap_or(0); let col = self.src[start_of_line..self.offset].chars().count(); diff --git a/packages/notion-to-blog/src/main.rs b/packages/notion-to-blog/src/main.rs index a742885461..98d29902ef 100644 --- a/packages/notion-to-blog/src/main.rs +++ b/packages/notion-to-blog/src/main.rs @@ -222,8 +222,7 @@ fn transform_markdown(content: &str, image_mapping: &HashMap) -> // Check if this is a video file - if so, convert to image syntax let url_decoded = dest_url.replace("%20", " "); if let Some(filename) = Path::new(&url_decoded).file_name().and_then(|s| s.to_str()) - { - if is_media_file(filename) { + && is_media_file(filename) { // Convert link to image for video files events.push(Event::Start(Tag::Image { link_type, @@ -233,7 +232,6 @@ fn transform_markdown(content: &str, image_mapping: &HashMap) -> })); continue; } - } // Regular link handling in_link = true; @@ -456,11 +454,10 @@ fn process_image_url(url: &str, image_mapping: &HashMap) -> Stri // Extract filename from URL let url_decoded = url.replace("%20", " "); - if let Some(filename) = Path::new(&url_decoded).file_name().and_then(|s| s.to_str()) { - if let Some(new_name) = image_mapping.get(filename) { + if let Some(filename) = Path::new(&url_decoded).file_name().and_then(|s| s.to_str()) + && let Some(new_name) = image_mapping.get(filename) { return format!("./assets/{}", new_name); } - } // Fallback: clean up the URL by removing URL encoding format!("./assets/{}", url.replace("%20", "-").to_lowercase()) diff --git a/packages/search/search-macro/src/lib.rs b/packages/search/search-macro/src/lib.rs index f6b59acc16..6a0328a1aa 100644 --- a/packages/search/search-macro/src/lib.rs +++ b/packages/search/search-macro/src/lib.rs @@ -7,7 +7,7 @@ use syn::LitStr; #[proc_macro] pub fn load_search_index(input: TokenStream) -> TokenStream { match syn::parse::(input) { - Ok(input) => generate_search_index(input).into(), + Ok(input) => generate_search_index(input), Err(err) => err.to_compile_error().into(), } } @@ -19,7 +19,7 @@ fn generate_search_index(id: LitStr) -> TokenStream { let name = id.value(); let index_path = PathBuf::from(format!("{}/dioxus_search/index_{}.bin", target_dir, name)); let index_str = index_path.to_str().unwrap(); - if index_path.exists() && std::fs::read(&index_path).unwrap().len() > 0 { + if index_path.exists() && !std::fs::read(&index_path).unwrap().is_empty() { quote!{ { const INDEX_BYTES: &[u8] = include_bytes!(#index_str); diff --git a/packages/search/search-shared/src/lib.rs b/packages/search/search-shared/src/lib.rs index 4083659761..6e10bdca79 100644 --- a/packages/search/search-shared/src/lib.rs +++ b/packages/search/search-shared/src/lib.rs @@ -326,7 +326,7 @@ impl SearchIndexMapping for BaseDirectoryMapping { fn map_route(&self, route: R) -> Option { let route = route.to_string(); let (route, _) = route.split_once('#').unwrap_or((&route, "")); - let (route, _) = route.split_once('?').unwrap_or((&route, "")); + let (route, _) = route.split_once('?').unwrap_or((route, "")); let route = PathBuf::from(route).join("index.html"); Some(route) } From 69700fd6aca52989d7ba448738df59964d629894 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 10:30:24 -0500 Subject: [PATCH 46/58] fix formatting --- .../packages/mdbook-gen-example/build.rs | 1 - packages/notion-to-blog/src/main.rs | 28 ++++++++++--------- packages/playground/model/src/server.rs | 16 ++--------- .../src/dx_components/accordion/mod.rs | 2 +- .../src/dx_components/button/mod.rs | 2 +- .../src/dx_components/dialog/mod.rs | 2 +- .../playground/src/dx_components/mod.rs | 4 +-- .../src/dx_components/select/mod.rs | 2 +- packages/playground/playground/src/ws.rs | 3 +- packages/playground/server/src/app.rs | 1 - .../playground/server/src/build/builder.rs | 28 +++++++++++-------- .../playground/server/src/build/cleanup.rs | 12 ++++---- .../playground/server/src/build/watcher.rs | 23 +++++++-------- 13 files changed, 60 insertions(+), 64 deletions(-) diff --git a/packages/include_mdbook/packages/mdbook-gen-example/build.rs b/packages/include_mdbook/packages/mdbook-gen-example/build.rs index 7c21db693f..4c1c4b1204 100644 --- a/packages/include_mdbook/packages/mdbook-gen-example/build.rs +++ b/packages/include_mdbook/packages/mdbook-gen-example/build.rs @@ -1,4 +1,3 @@ - fn main() { // // re-run only if the "example-book" directory changes // println!("cargo:rerun-if-changed=example-book"); diff --git a/packages/notion-to-blog/src/main.rs b/packages/notion-to-blog/src/main.rs index 98d29902ef..32b195b3f6 100644 --- a/packages/notion-to-blog/src/main.rs +++ b/packages/notion-to-blog/src/main.rs @@ -222,16 +222,17 @@ fn transform_markdown(content: &str, image_mapping: &HashMap) -> // Check if this is a video file - if so, convert to image syntax let url_decoded = dest_url.replace("%20", " "); if let Some(filename) = Path::new(&url_decoded).file_name().and_then(|s| s.to_str()) - && is_media_file(filename) { - // Convert link to image for video files - events.push(Event::Start(Tag::Image { - link_type, - dest_url: processed_url.into(), - title, - id, - })); - continue; - } + && is_media_file(filename) + { + // Convert link to image for video files + events.push(Event::Start(Tag::Image { + link_type, + dest_url: processed_url.into(), + title, + id, + })); + continue; + } // Regular link handling in_link = true; @@ -455,9 +456,10 @@ fn process_image_url(url: &str, image_mapping: &HashMap) -> Stri let url_decoded = url.replace("%20", " "); if let Some(filename) = Path::new(&url_decoded).file_name().and_then(|s| s.to_str()) - && let Some(new_name) = image_mapping.get(filename) { - return format!("./assets/{}", new_name); - } + && let Some(new_name) = image_mapping.get(filename) + { + return format!("./assets/{}", new_name); + } // Fallback: clean up the URL by removing URL encoding format!("./assets/{}", url.replace("%20", "-").to_lowercase()) diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 81b8155b99..8bc502ea2d 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -66,11 +66,7 @@ impl TryFrom for CargoDiagnostic { let message = diagnostic.message; // Collect spans - let spans = diagnostic - .spans - .iter() - .map(|s| s.clone().into()) - .collect(); + let spans = diagnostic.spans.iter().map(|s| s.clone().into()).collect(); Ok(Self { target_crate: Some(value.target.name), @@ -92,11 +88,7 @@ impl TryFrom for CargoDiagnostic { let message = value.message; // Collect spans - let spans = value - .spans - .iter() - .map(|s| s.clone().into()) - .collect(); + let spans = value.spans.iter().map(|s| s.clone().into()).collect(); Ok(Self { target_crate: None, @@ -108,8 +100,7 @@ impl TryFrom for CargoDiagnostic { } } - -impl From for CargoDiagnosticSpan{ +impl From for CargoDiagnosticSpan { fn from(value: DiagnosticSpan) -> Self { Self { is_primary: value.is_primary, @@ -123,7 +114,6 @@ impl From for CargoDiagnosticSpan{ } } - /// IntoResponse for app errors. impl IntoResponse for AppError { fn into_response(self) -> axum::response::Response { diff --git a/packages/playground/playground/src/dx_components/accordion/mod.rs b/packages/playground/playground/src/dx_components/accordion/mod.rs index 9a8ae55652..2590c01321 100644 --- a/packages/playground/playground/src/dx_components/accordion/mod.rs +++ b/packages/playground/playground/src/dx_components/accordion/mod.rs @@ -1,2 +1,2 @@ mod component; -pub use component::*; \ No newline at end of file +pub use component::*; diff --git a/packages/playground/playground/src/dx_components/button/mod.rs b/packages/playground/playground/src/dx_components/button/mod.rs index 9a8ae55652..2590c01321 100644 --- a/packages/playground/playground/src/dx_components/button/mod.rs +++ b/packages/playground/playground/src/dx_components/button/mod.rs @@ -1,2 +1,2 @@ mod component; -pub use component::*; \ No newline at end of file +pub use component::*; diff --git a/packages/playground/playground/src/dx_components/dialog/mod.rs b/packages/playground/playground/src/dx_components/dialog/mod.rs index 9a8ae55652..2590c01321 100644 --- a/packages/playground/playground/src/dx_components/dialog/mod.rs +++ b/packages/playground/playground/src/dx_components/dialog/mod.rs @@ -1,2 +1,2 @@ mod component; -pub use component::*; \ No newline at end of file +pub use component::*; diff --git a/packages/playground/playground/src/dx_components/mod.rs b/packages/playground/playground/src/dx_components/mod.rs index a3f57f1644..0bdf2f2e9a 100644 --- a/packages/playground/playground/src/dx_components/mod.rs +++ b/packages/playground/playground/src/dx_components/mod.rs @@ -1,5 +1,5 @@ // AUTOGENERTED Components module -pub mod dialog; +pub mod accordion; pub mod button; +pub mod dialog; pub mod select; -pub mod accordion; diff --git a/packages/playground/playground/src/dx_components/select/mod.rs b/packages/playground/playground/src/dx_components/select/mod.rs index 9a8ae55652..2590c01321 100644 --- a/packages/playground/playground/src/dx_components/select/mod.rs +++ b/packages/playground/playground/src/dx_components/select/mod.rs @@ -1,2 +1,2 @@ mod component; -pub use component::*; \ No newline at end of file +pub use component::*; diff --git a/packages/playground/playground/src/ws.rs b/packages/playground/playground/src/ws.rs index cfebba0cf7..6f5dcfa422 100644 --- a/packages/playground/playground/src/ws.rs +++ b/packages/playground/playground/src/ws.rs @@ -44,7 +44,7 @@ impl Socket { } /// Handles a websocket message, returning true if further messages shouldn't be handled. -pub fn handle_message(mut build: Store, message: SocketMessage) { +pub fn handle_message(mut build: Store, message: SocketMessage) { match message { SocketMessage::BuildStage(stage) => build.set_stage(BuildStage::Building(stage)), SocketMessage::QueuePosition(position) => build.set_stage(BuildStage::Queued(position)), @@ -72,5 +72,4 @@ pub fn handle_message(mut build: Store, message: SocketMessage) { SocketMessage::RateLimited(time) => build.set_stage(BuildStage::Waiting(time)), _ => {} } - } diff --git a/packages/playground/server/src/app.rs b/packages/playground/server/src/app.rs index 8a7c8956ce..f40865bd8b 100644 --- a/packages/playground/server/src/app.rs +++ b/packages/playground/server/src/app.rs @@ -224,7 +224,6 @@ impl AppState { let is_building = Arc::new(AtomicBool::new(false)); let build_queue_tx = start_build_watcher(env.clone(), is_building.clone()); - let build_govener = Arc::new(RateLimiter::keyed( Quota::with_period(Duration::from_secs(5)) .expect("period is non-zero") diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 6da0361b5a..d07f729fdc 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -206,7 +206,10 @@ fn start_limited_process(mut command: Command, env: &EnvVars) -> Result) -> Result, BuildError> { +async fn dx_build( + request: &BuildRequest, + env: Arc, +) -> Result, BuildError> { // If there is a previous build, get the cache dir for that build if it exists let previous_build_cache_dir = request .previous_build_id @@ -280,11 +283,14 @@ async fn start_dx_build( } } - let BuildResult { logs, patch, status } = tokio::task::spawn_blocking({ + let BuildResult { + logs, + patch, + status, + } = tokio::task::spawn_blocking({ let request = request.clone(); - move || { - process_build_messages(&mut child, &env, &request) - }}) + move || process_build_messages(&mut child, &env, &request) + }) .await?; // Check if the build was successful. @@ -315,11 +321,7 @@ struct BuildResult { } /// Process the stdout and stderr of a dx build process, returning the logs and any hotpatch jump table -fn process_build_messages( - child: &mut Child, - env: &EnvVars, - request: &BuildRequest, -) -> BuildResult { +fn process_build_messages(child: &mut Child, env: &EnvVars, request: &BuildRequest) -> BuildResult { let stderr = child.stderr.take().expect("dx stdout should exist"); let stdout = child.stdout.take().expect("dx stdout should exist"); let mut stdout_reader = BufReader::new(stdout).lines(); @@ -340,7 +342,11 @@ fn process_build_messages( let status = child.wait(); - BuildResult { logs, patch, status } + BuildResult { + logs, + patch, + status, + } } /// Limit a child process's resource usage. This prevents extremely long builds or excessive memory usage from crashing the server. diff --git a/packages/playground/server/src/build/cleanup.rs b/packages/playground/server/src/build/cleanup.rs index 9f629797d6..10e425f167 100644 --- a/packages/playground/server/src/build/cleanup.rs +++ b/packages/playground/server/src/build/cleanup.rs @@ -86,12 +86,12 @@ async fn check_project_cleanup(env: &EnvVars) -> Result<(), io::Error> { while let Some(entry) = wasm_dir.next_entry().await? { let entry_path = entry.path(); if let Some(name) = entry_path.file_name() - && name.to_string_lossy().contains("patch") { - let patch_size = - entry.metadata().await.map(|m| m.len()).unwrap_or(0); - _ = tokio::fs::remove_file(&entry_path).await; - size -= patch_size; - } + && name.to_string_lossy().contains("patch") + { + let patch_size = entry.metadata().await.map(|m| m.len()).unwrap_or(0); + _ = tokio::fs::remove_file(&entry_path).await; + size -= patch_size; + } } } } else { diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index 5443e2d805..641489e063 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -75,19 +75,20 @@ fn stop_build(builder: &mut Builder, pending_builds: &mut VecDeque // Check if the ongoing build is the cancelled build. let current_build_id = builder.current_build().map(|b| b.id); if let Some(current_build_id) = current_build_id - && id == current_build_id { - builder.stop_current(); - - // Start the next build request. - let next_request = pending_builds.pop_front(); - if let Some(request) = next_request { - builder.start(request); - } - - update_queue_positions(pending_builds); - return; + && id == current_build_id + { + builder.stop_current(); + + // Start the next build request. + let next_request = pending_builds.pop_front(); + if let Some(request) = next_request { + builder.start(request); } + update_queue_positions(pending_builds); + return; + } + // Try finding the build in the queue let mut matching_id = None; From 6da87d9e8bd5ba12143e73d54b36b366ee190e92 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 10:33:08 -0500 Subject: [PATCH 47/58] more cleanup --- packages/playground/model/src/lib.rs | 4 ++++ packages/playground/model/src/server.rs | 11 ++++------- packages/playground/server/src/build/builder.rs | 4 +--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/playground/model/src/lib.rs b/packages/playground/model/src/lib.rs index 9a8f7edcdf..730536afd4 100644 --- a/packages/playground/model/src/lib.rs +++ b/packages/playground/model/src/lib.rs @@ -20,8 +20,11 @@ mod web; /// The result of a build #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum BuildResult { + /// The project was built and is now available under the uuid Built(Uuid), + /// The project was hotpatched HotPatched(JumpTable), + /// The build failed with an error message Failed(String), } @@ -40,6 +43,7 @@ pub enum SocketMessage { } impl SocketMessage { + /// Check if the socket message is the finished variant pub fn is_finished(&self) -> bool { matches!(self, SocketMessage::BuildFinished(_)) } diff --git a/packages/playground/model/src/server.rs b/packages/playground/model/src/server.rs index 8bc502ea2d..217e05e4e0 100644 --- a/packages/playground/model/src/server.rs +++ b/packages/playground/model/src/server.rs @@ -78,11 +78,8 @@ impl TryFrom for CargoDiagnostic { } } -/// TryFrom that fails for data we don't care about from cargo. -impl TryFrom for CargoDiagnostic { - type Error = (); - - fn try_from(value: Diagnostic) -> Result { +impl From for CargoDiagnostic { + fn from(value: Diagnostic) -> Self { let level = CargoLevel::Error; let message = value.message; @@ -90,13 +87,13 @@ impl TryFrom for CargoDiagnostic { // Collect spans let spans = value.spans.iter().map(|s| s.clone().into()).collect(); - Ok(Self { + Self { target_crate: None, level, message, spans, rendered: value.rendered, - }) + } } } diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index d07f729fdc..12956affbc 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -416,9 +416,7 @@ fn process_dx_message(env: &EnvVars, request: &BuildRequest, message: String) -> .send(BuildMessage::CargoDiagnostic(diagnostic)) } StructuredOutput::RustcOutput { message } => { - let Ok(diagnostic) = CargoDiagnostic::try_from(message) else { - return None; - }; + let diagnostic = CargoDiagnostic::from(message); if !from_main_crate(&diagnostic) { return None; From ce3a2bde7907e5baacec08db082124a74e9465ab Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 11:01:38 -0500 Subject: [PATCH 48/58] fix production server url --- packages/docsite/src/components/playground.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/docsite/src/components/playground.rs b/packages/docsite/src/components/playground.rs index adc034b9c8..715ebebd67 100644 --- a/packages/docsite/src/components/playground.rs +++ b/packages/docsite/src/components/playground.rs @@ -11,7 +11,7 @@ const URLS: PlaygroundUrls = PlaygroundUrls { #[cfg(feature = "production")] const URLS: PlaygroundUrls = PlaygroundUrls { socket: "wss://docsite-playground.fly.dev/ws", - server: "https://docsite-playground.fly.dev/built/", + server: "https://docsite-playground.fly.dev", location: "https://dioxuslabs.com/playground", }; From c77516d19957864a309c36f362e1c682348f80a3 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 14 Oct 2025 11:22:38 -0500 Subject: [PATCH 49/58] remove _dioxus handler --- packages/playground/server/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/playground/server/src/main.rs b/packages/playground/server/src/main.rs index ade040678c..ba20376366 100644 --- a/packages/playground/server/src/main.rs +++ b/packages/playground/server/src/main.rs @@ -72,8 +72,6 @@ async fn main() { .route("/{:id}", get(get_shared_project)); let app = Router::new() - // Just wait forever for the devtools to connect. We handle them through the ws route bellow. - .route("/_dioxus", get(std::future::pending::>)) // Every build gets a websocket connection to report build progress. .route("/ws", get(ws::ws_handler)) // The built routes for project that are cached. From 66b94a4665ccb69ba8a4c76900c05e9934e23284 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 20 Oct 2025 09:05:03 -0500 Subject: [PATCH 50/58] update lockfile --- Cargo.lock | 559 +++++++++++++++++++++++++++-------------------------- 1 file changed, 281 insertions(+), 278 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c70169cb0b..fbb0159068 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -148,7 +148,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -223,7 +223,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -245,7 +245,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -256,7 +256,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -327,7 +327,7 @@ checksum = "ebb4bd301db2e2ca1f5be131c24eb8ebf2d9559bc3744419e93baf8ddea7e670" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -499,7 +499,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -543,11 +543,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -646,7 +646,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cairo-sys-rs", "glib", "libc", @@ -738,9 +738,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -830,7 +830,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -863,7 +863,7 @@ version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block", "cocoa-foundation", "core-foundation 0.10.1", @@ -879,7 +879,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block", "core-foundation 0.10.1", "core-graphics-types", @@ -987,9 +987,9 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62fa1b64a9432bd3ec5dfc7ed000b03a6bf2edb9e67bbe15e47c319506198c4c" +checksum = "627e3e7e337db21d15bdea3fe61b58956c27d05db2c1ab8336d819736bf81b46" dependencies = [ "const-serialize-macro", "serde", @@ -997,13 +997,13 @@ dependencies = [ [[package]] name = "const-serialize-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983992de580b235fff6a419247007b298cd2e7da0f11ee2491152cae49fa93f7" +checksum = "684474cb657c2b14dbc8c464d66bc1d84739f0cb7c4a6fe7c6f557ff2621cee9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -1126,7 +1126,7 @@ version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.10.1", "core-graphics-types", "foreign-types 0.5.0", @@ -1139,7 +1139,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.10.1", "libc", ] @@ -1272,7 +1272,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -1295,7 +1295,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -1306,7 +1306,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -1359,7 +1359,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -1379,7 +1379,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "unicode-xid", ] @@ -1401,9 +1401,9 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfab61caa2b10a905998c9cb5cb1717b8ce858f3cec009efb19fc91b159f2120" +checksum = "f06e0ef1f6209137851223fdf5e586ab2e43d69cab0297410e815437d379f862" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -1434,9 +1434,9 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dcd9492970659cf77c1afcb79270ad62a3bf5ab1d90f12f565b26fd9ba2507" +checksum = "be011c4555d097c3a144df7e792450d99b295beb50d99c27741b4044d5cc4751" dependencies = [ "dioxus-cli-config", "http", @@ -1456,9 +1456,9 @@ dependencies = [ [[package]] name = "dioxus-autofmt" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92bd52f33ff5f4d9cb80b4b2f72cb4bb7220d81bb4be4d6499c63abfb4ab7e37" +checksum = "20f67575e65f1acf1281fca7295d41ab451302e1dbce45b7066c254946e2cc29" dependencies = [ "dioxus-rsx", "prettyplease", @@ -1466,23 +1466,23 @@ dependencies = [ "quote", "regex", "serde", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-cli-config" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "231a1a85b7977e938e55db0c9bd04893830e8ee72a5f0b610ce927939887718f" +checksum = "f5f7d514061948391f47eb4b0ffc3f5fb8291e1ece0aee17f72b01826b2a159e" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79022b079edb218464680678b6c9069f417f2185be021675be060e5c3be394d8" +checksum = "93a35d906fd9ddb8a9b9756288ace7cabaf3d68ccd8cccced8c36eccff2dcef0" dependencies = [ "proc-macro2", "quote", @@ -1490,15 +1490,15 @@ dependencies = [ [[package]] name = "dioxus-config-macros" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee30f3e7b9faa3214de9e67e1ee39a4c1cccc600286cd31ad9f4b662d1bd62a4" +checksum = "2074df79d509421e17c3417101768bccf096935905ce52e5582a9c7ffdb86a9c" [[package]] name = "dioxus-core" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cdb8ce8b66e981a0ce943184efa6dcdce06852f701642e0570648bec313596a" +checksum = "96e470c108ce1fec04e9945646e0d40a96296ae992a74baa6f1db02e94929e3b" dependencies = [ "anyhow", "const_format", @@ -1519,28 +1519,28 @@ dependencies = [ [[package]] name = "dioxus-core-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf7bb96b7cd7bea18be827b720f35f15db8b493d1832e69277539eaf336897a" +checksum = "b1e32977d31f9c8a0a11214a7b0858d16bd8f9d873290b933089e2c78381c75b" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-core-types" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6ed5dc0c2fac63830b52c613be5380fc1d9e48981b65cd7a1771c725ba4b69" +checksum = "35a4c40f3d16dac27385d87dbe0f371960d463deb98da46faa070a5f56b4b85e" [[package]] name = "dioxus-desktop" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9417be8a0d0bfdcdecb0a28bd9728bfd23bcc24d2b1d624e0298d8cbd576a911" +checksum = "1c5c3de3657fb5041b5ab2e3ea129e19e47bb38da3f1e049c50f534d4c259b77" dependencies = [ "async-trait", "base64 0.22.1", @@ -1564,7 +1564,7 @@ dependencies = [ "global-hotkey", "infer", "jni", - "lazy-js-bundle 0.7.0-rc.1", + "lazy-js-bundle 0.7.0-rc.2", "libc", "muda", "ndk", @@ -1593,9 +1593,9 @@ dependencies = [ [[package]] name = "dioxus-devtools" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee75595feb78aaf4101f95699b1323bbf7910ce5cfeec730725ec7781c88317" +checksum = "c467d13d99cfdc7e41e158196d2db48fb523e3b308f59812491dbff3dbf4083e" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -1614,9 +1614,9 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc965cdbe70c85e15e1d172546213dde0941afa2e1e0ff72510a5eea69db03e4" +checksum = "16cc2c41ba03e3286f990b5f71e1380cca8e928a340deeaa9fdb45bd0febe630" dependencies = [ "dioxus-core", "serde", @@ -1739,9 +1739,9 @@ dependencies = [ [[package]] name = "dioxus-document" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "923edda3e26de60eb1954bf8bbe562dab891ee207f97bded3469b7b97ec27325" +checksum = "1eaaf40620c59aac329f1408f5313524aaced4732b4888a9457fd877bbb62504" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -1750,7 +1750,7 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle 0.7.0-rc.1", + "lazy-js-bundle 0.7.0-rc.2", "serde", "serde_json", "tracing", @@ -1758,9 +1758,9 @@ dependencies = [ [[package]] name = "dioxus-dx-wire-format" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c63dba4f2f6e44cefbc8f6969abbe61fd497eaaa0447c365db853880d94d0a0" +checksum = "a62d6008e41248dd3436a7a41984b7ebd55acda4a4dce0d0e9f48484743f045e" dependencies = [ "cargo_metadata", "manganis-core", @@ -1771,9 +1771,9 @@ dependencies = [ [[package]] name = "dioxus-fullstack" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f4bf3345e91a5c7fa27ada6c27722b2cdec39b6d58f55869d9bde7fce0204c8" +checksum = "220b6e0f43293671b3b0253856cda81c001974d881bdccc7b8f51371fd9db0be" dependencies = [ "anyhow", "async-stream", @@ -1836,9 +1836,9 @@ dependencies = [ [[package]] name = "dioxus-fullstack-core" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04f171276ca69d5d2266c786b390f281ed4c2b375db370d20d3eda0ebb5e891" +checksum = "5d25649cb002e51e0d8a66741507f8b18bed38de35c9493909c784bc80494a30" dependencies = [ "anyhow", "axum-core 0.5.5", @@ -1862,23 +1862,23 @@ dependencies = [ [[package]] name = "dioxus-fullstack-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d218f17463e0bf255599afe1ef477ca9049e549491032a57e618ee1bf65a6b17" +checksum = "243bac70d573041c1aeb83555c95c44e9d7f74ec26b9a041594c570333270973" dependencies = [ "const_format", "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "xxhash-rust", ] [[package]] name = "dioxus-history" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07f1cb988bfae15dc66564616adc98a89fdfbb5e5e94ac28f8a2f2590886ded" +checksum = "1b6c2a19fefdcd96c1ef0a4eb51164b0b6f73fd606da29df72860df6ea9d8fb5" dependencies = [ "dioxus-core", "tracing", @@ -1886,9 +1886,9 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3843e73fb8f199326d9b77c2dce6c89dfd47f77cbd87dd50fedfb4a2f9fc8015" +checksum = "19ec49a9bab65751fb978cd965e6aa34df2b8eb09ce7898b6926daf9143ccfe0" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1903,9 +1903,9 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5341444c368b99d119646256292cb6b1034458f53280cff3b9dd9f5c992baab2" +checksum = "524255c586ff136e1c93a58c277d8abacd1a4c3edfc80e269ad432ed6a079854" dependencies = [ "async-trait", "bytes", @@ -1921,7 +1921,7 @@ dependencies = [ "futures-util", "generational-box", "keyboard-types", - "lazy-js-bundle 0.7.0-rc.1", + "lazy-js-bundle 0.7.0-rc.2", "rustversion", "serde", "serde_json", @@ -1931,27 +1931,27 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c19513628504ec7059812331d60e32d8d37b1f48c3252e5ad757db3e65b48c3" +checksum = "a75ef68806ad8007a684735fd8628c3bbb3ba31dd6d93f95b68fcf78999d3774" dependencies = [ "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-interpreter-js" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "352115c6688009b4319f5b510d7a438e67fa655394310a3706cffa7f6218b93e" +checksum = "1dabf9bd9e467c2b401cdad2eafa5183cb33e1cfb31e34edd7c7c919b997fa30" dependencies = [ "dioxus-core", "dioxus-core-types", "dioxus-html", "js-sys", - "lazy-js-bundle 0.7.0-rc.1", + "lazy-js-bundle 0.7.0-rc.2", "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", @@ -1963,9 +1963,9 @@ dependencies = [ [[package]] name = "dioxus-liveview" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3a125beceef0c208f32076a7d0e71afc11b4d4fb2a24ca02207b46103e69466" +checksum = "2a20bd82762ada62e9bf7bd5503e94417479b75c11944420e490d09957f48a16" dependencies = [ "axum 0.8.6", "dioxus-cli-config", @@ -1991,9 +1991,9 @@ dependencies = [ [[package]] name = "dioxus-logger" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567f266396a2bb65b13bbadd78241a70dfc8bd233aecc2b37f19237532c9ab21" +checksum = "3fb24661898206648dba4e279590d3e4e4a79a7a28e4dde47a0b8db06373e26e" dependencies = [ "dioxus-cli-config", "tracing", @@ -2029,7 +2029,7 @@ dependencies = [ "serde", "serde-wasm-bindgen", "serde_json", - "syn 2.0.106", + "syn 2.0.107", "thiserror 2.0.17", "tracing", "uuid", @@ -2039,7 +2039,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#3571d90aa55773c59b05119d9fff8879da6b8a3d" +source = "git+https://github.com/DioxusLabs/components#723d43cd1b4e433599881139bafad4b07cdbae46" dependencies = [ "dioxus", "dioxus-time", @@ -2050,9 +2050,9 @@ dependencies = [ [[package]] name = "dioxus-router" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1ec9ea8a84b8b8eabae0f661e1926267b498d9a7265a31731d755b95abbe61" +checksum = "177c7e319b21026b8dd768a3c5dc8279b96716eb18a74d453fea702e5a9078ce" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2071,9 +2071,9 @@ dependencies = [ [[package]] name = "dioxus-router-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6e8cb648e2146ba825c6a66c8b678f51a620d5f70852b7eb1c98b0e8286e8c" +checksum = "0e4746d9a12973c55dac4f091984a8a5d4caafa54e254a6a2a3242a678c750d7" dependencies = [ "base16", "digest", @@ -2081,26 +2081,26 @@ dependencies = [ "quote", "sha2", "slab", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-rsx" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7dfd6a789e69a5f952fbc8eeb1a8866014e0abee3882ebaceb139a4e12709a" +checksum = "a5d857223d955440236aa657149de2c83774bd4c4ad9a3db8081a444f22c401e" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-rsx-hotreload" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5d348d18411c1e1a78b9f7d64c36495d63597687d5a398e82e2d887ccf00a" +checksum = "ac64c013d858bc850ee07517a9f2caf8a8e9ad113cf4792e303a71b013c3c92b" dependencies = [ "dioxus-core", "dioxus-core-types", @@ -2109,15 +2109,15 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.106", + "syn 2.0.107", "tracing", ] [[package]] name = "dioxus-rsx-rosetta" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51539cc91794445e60c897711047a6d64c5495aa797630181039b2b954e1279" +checksum = "f82f92b58fd6d12801fe7aa318b7fd89bbe4614c685bac90e510e5e632a17840" dependencies = [ "convert_case 0.8.0", "dioxus-autofmt", @@ -2127,13 +2127,13 @@ dependencies = [ "htmlentity", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-sdk" -version = "0.7.0-rc.1" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" +version = "0.7.0-rc.2" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#83917facef7df2bb88fbba7d11e26e08f939b060" dependencies = [ "dioxus-time", "dioxus-util", @@ -2163,7 +2163,7 @@ name = "dioxus-search-macro" version = "0.1.0" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2185,9 +2185,9 @@ dependencies = [ [[package]] name = "dioxus-server" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac0a65350e056ee9b8116dca4f19ed16d290e5610f7593b3cabd756642020b4a" +checksum = "12715f675d60a0aa843f12e9391433de0259ba1f0785d34c8235c6f9ed8214af" dependencies = [ "anyhow", "async-trait", @@ -2243,9 +2243,9 @@ dependencies = [ [[package]] name = "dioxus-signals" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1b204dc460bef2ff0c92e4044d58090fe5209fd93537dbb6f344fa379e835f" +checksum = "63fe88d5974e8ca0513e727ba863eb9b6f64fa6d2e90e9aa2ce1f57fe7180ec4" dependencies = [ "dioxus-core", "futures-channel", @@ -2259,9 +2259,9 @@ dependencies = [ [[package]] name = "dioxus-ssr" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8d580119df51b292f91f77085a0adc5eca99347c483ad3e3893c827a179913" +checksum = "01a85dedbe24dddd6931fd46daa7c68f604819f06bb1545e48ec15db778f17ae" dependencies = [ "askama_escape 0.13.0", "dioxus-core", @@ -2271,9 +2271,9 @@ dependencies = [ [[package]] name = "dioxus-stores" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560f16579c9a4c3fb81b41e6e5b9018e2e91b5c57d43469a37cf22807ca47acc" +checksum = "ec01dae556a5519000cde2a283adfdfafbb33a5378d74d9fd2d708d7727cc253" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2282,20 +2282,20 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf06d8e91f5af4b29e74a8ebaf7b6c778774e09a0f6551bf40409e263c781cdb" +checksum = "74c06ec893540e33c111b00c562783e173d74fc136f5b35a7d537d626e260c34" dependencies = [ "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] name = "dioxus-time" -version = "0.7.0-rc.1" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" +version = "0.7.0-rc.2" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#83917facef7df2bb88fbba7d11e26e08f939b060" dependencies = [ "dioxus", "futures", @@ -2305,8 +2305,8 @@ dependencies = [ [[package]] name = "dioxus-util" -version = "0.7.0-rc.1" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" +version = "0.7.0-rc.2" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#83917facef7df2bb88fbba7d11e26e08f939b060" dependencies = [ "dioxus", "serde", @@ -2314,9 +2314,9 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8824596741fc373f7b8600031016446c19d5e2f36a3bc0420e3b80466a2fd05c" +checksum = "c1e77d5ea91353c1f43429d8efd145e0881d05de46d8366bd3d2c53c6f5fc80d" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2333,7 +2333,7 @@ dependencies = [ "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle 0.7.0-rc.1", + "lazy-js-bundle 0.7.0-rc.2", "rustc-hash 2.1.1", "send_wrapper", "serde", @@ -2348,8 +2348,8 @@ dependencies = [ [[package]] name = "dioxus-window" -version = "0.7.0-rc.1" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#5ec9cdf922ab8b038f40b4112464c69b3bd6d76a" +version = "0.7.0-rc.2" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#83917facef7df2bb88fbba7d11e26e08f939b060" dependencies = [ "dioxus", "dioxus-config-macro", @@ -2434,7 +2434,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "libc", "objc2", @@ -2448,7 +2448,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2480,7 +2480,7 @@ checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2594,7 +2594,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2615,7 +2615,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2635,7 +2635,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2746,7 +2746,7 @@ checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2796,6 +2796,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2823,7 +2829,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -2951,7 +2957,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -3086,9 +3092,9 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93e10f2f89a54e58670ad86e1896db4800b91af59ed55a2dc195d2ea5fecfa4" +checksum = "6e35e810c6f9d98e175e513e02b7068bfa49ed9773f95f35636073e7bba7e166" dependencies = [ "parking_lot", "tracing", @@ -3106,12 +3112,12 @@ dependencies = [ [[package]] name = "gethostname" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ "rustix", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -3149,15 +3155,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", "wasm-bindgen", ] @@ -3209,7 +3215,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "futures-channel", "futures-core", "futures-executor", @@ -3237,7 +3243,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -3350,7 +3356,7 @@ dependencies = [ "futures-sink", "futures-timer", "futures-util", - "getrandom 0.3.3", + "getrandom 0.3.4", "hashbrown 0.15.5", "nonzero_ext", "parking_lot", @@ -3411,7 +3417,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -3426,7 +3432,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.11.4", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3485,7 +3491,7 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -3493,6 +3499,11 @@ name = "hashbrown" version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -3995,9 +4006,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.11.4" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", "hashbrown 0.16.0", @@ -4042,7 +4053,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -4157,7 +4168,7 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] @@ -4177,7 +4188,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "serde", "unicode-segmentation", ] @@ -4202,7 +4213,7 @@ checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" dependencies = [ "cssparser 0.29.6", "html5ever 0.29.1", - "indexmap 2.11.4", + "indexmap 2.12.0", "selectors 0.24.0", ] @@ -4214,9 +4225,9 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8697a8442f28425b7263aed3b2e25c94b273fb18f503b8bfb188865dfdcbb62b" +checksum = "55fbddf68a736ea972196a85a7d47d6b6c0f49beba3c9c1dc5d90cc0875c91bf" [[package]] name = "lazy_static" @@ -4296,7 +4307,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", ] @@ -4385,11 +4396,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe949189f46fabb938b3a9a0be30fdd93fd8a09260da863399a8cf3db756ec8" +checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.0", ] [[package]] @@ -4412,7 +4423,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -4448,9 +4459,9 @@ dependencies = [ [[package]] name = "manganis" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d99d7bdf99077e989ef8b15195ac7b070f2274755560239b2ce9b15d5d3542" +checksum = "a08c957e10139a9772143ac49450a927d50bafea8fa4333f13b7bce4ace9ae63" dependencies = [ "const-serialize", "manganis-core", @@ -4459,9 +4470,9 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05ca73545ec919930d103e66c1057f3a3dac273ac27db721a358546e7ce7aed" +checksum = "94b859887ea5cce08d9df9e79132867682492215695d6be32775ad0571a6fba0" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -4471,16 +4482,16 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc3b11e27e62b12f371afb4d703ea3ca119a6e48736fae0e5f0f5c9642e2879" +checksum = "2f124aad6f02a80730e0d3364af0f94b83496a441776ad0a27d26c25c981052c" dependencies = [ "dunce", "macro-string", "manganis-core", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -4519,7 +4530,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -4589,7 +4600,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.106", + "syn 2.0.107", "syntect", ] @@ -4603,7 +4614,7 @@ dependencies = [ "mdbook-shared", "prettyplease", "serde", - "syn 2.0.106", + "syn 2.0.107", "use-mdbook", ] @@ -4623,7 +4634,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.106", + "syn 2.0.107", "syntect", ] @@ -4710,13 +4721,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -4808,7 +4819,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "jni-sys", "log", "ndk-sys", @@ -4844,7 +4855,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -4931,7 +4942,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -4975,9 +4986,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -4985,14 +4996,14 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5020,7 +5031,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-core-foundation", @@ -5033,7 +5044,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "dispatch2", "objc2", ] @@ -5044,7 +5055,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2-core-foundation", ] @@ -5069,7 +5080,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-core-foundation", @@ -5081,7 +5092,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -5093,7 +5104,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "objc2", "objc2-app-kit", @@ -5128,7 +5139,7 @@ version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "once_cell", "onig_sys", @@ -5146,11 +5157,11 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -5167,7 +5178,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5178,9 +5189,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", @@ -5300,7 +5311,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5433,7 +5444,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5500,7 +5511,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5528,7 +5539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64 0.22.1", - "indexmap 2.11.4", + "indexmap 2.12.0", "quick-xml 0.38.3", "serde", "time", @@ -5553,7 +5564,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "crc32fast", "fdeflate", "flate2", @@ -5632,7 +5643,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5710,7 +5721,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "version_check", ] @@ -5730,7 +5741,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5753,7 +5764,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -5787,7 +5798,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "getopts", "memchr", "unicase", @@ -5799,7 +5810,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "getopts", "memchr", "pulldown-cmark-escape", @@ -5905,7 +5916,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", @@ -6037,7 +6048,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -6114,7 +6125,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -6155,7 +6166,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -6330,7 +6341,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6375,7 +6386,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", @@ -6384,9 +6395,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.32" +version = "0.23.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c" dependencies = [ "once_cell", "ring", @@ -6480,7 +6491,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -6541,7 +6552,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd568a4c9bb598e291a08244a5c1f5a8a6650bee243b5b0f8dbb3d9cc1d87fe8" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cssparser 0.34.0", "derive_more 0.99.20", "fxhash", @@ -6611,7 +6622,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -6657,7 +6668,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -6850,7 +6861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7028,9 +7039,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subsecond" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3055f82c5a9f842a2a390a595a386343654a408790b3b20473c4b87a5c4ec3bf" +checksum = "5a334bfd43035f04ae713c873af627fb79b08f37cee4a9d653ac9f86ef9a1c48" dependencies = [ "js-sys", "libc", @@ -7047,9 +7058,9 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.0-rc.1" +version = "0.7.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61506acae0d5fc20d75943891ac9586e70cf7213c19fe0d0774e9d9648d4ee8" +checksum = "1f3495eea52ec3b187736bfee3522dd7fc2abc81cd8b60e1fd356a154e3a81d9" dependencies = [ "serde", ] @@ -7073,9 +7084,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" dependencies = [ "proc-macro2", "quote", @@ -7099,7 +7110,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7129,7 +7140,7 @@ version = "0.1.0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "syntect", ] @@ -7139,7 +7150,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -7169,11 +7180,11 @@ dependencies = [ [[package]] name = "tao" -version = "0.34.3" +version = "0.34.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7" +checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "block2", "core-foundation 0.10.1", "core-graphics", @@ -7216,7 +7227,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7232,7 +7243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys 0.61.2", @@ -7281,7 +7292,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7292,7 +7303,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7400,7 +7411,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -7531,7 +7542,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -7544,7 +7555,7 @@ version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -7555,7 +7566,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -7569,7 +7580,7 @@ version = "0.23.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" dependencies = [ - "indexmap 2.11.4", + "indexmap 2.12.0", "toml_datetime 0.7.3", "toml_parser", "winnow 0.7.13", @@ -7677,7 +7688,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.11.4", + "indexmap 2.12.0", "pin-project-lite", "slab", "sync_wrapper", @@ -7695,7 +7706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "async-compression", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytes", "futures-core", "futures-util", @@ -7721,7 +7732,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bytes", "futures-core", "futures-util", @@ -7804,7 +7815,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -8054,7 +8065,7 @@ version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "md-5", "serde", @@ -8134,7 +8145,7 @@ checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -8149,15 +8160,6 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" -dependencies = [ - "wasip2", -] - [[package]] name = "wasip2" version = "1.0.1+wasi-0.2.4" @@ -8192,7 +8194,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "wasm-bindgen-shared", ] @@ -8227,7 +8229,7 @@ checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8274,7 +8276,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "rustix", "wayland-backend", "wayland-scanner", @@ -8286,7 +8288,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -8336,9 +8338,9 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" +checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" dependencies = [ "core-foundation 0.10.1", "jni", @@ -8425,7 +8427,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -8543,7 +8545,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -8554,7 +8556,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -9038,15 +9040,15 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "synstructure", ] [[package]] name = "zbus" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" +checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ "async-broadcast", "async-recursion", @@ -9063,7 +9065,8 @@ dependencies = [ "tokio", "tracing", "uds_windows", - "windows-sys 0.60.2", + "uuid", + "windows-sys 0.61.2", "winnow 0.7.13", "zbus_macros", "zbus_names", @@ -9072,14 +9075,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.11.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" +checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "zbus_names", "zvariant", "zvariant_utils", @@ -9114,7 +9117,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -9134,7 +9137,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "synstructure", ] @@ -9174,7 +9177,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", ] [[package]] @@ -9203,9 +9206,9 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.7.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db" +checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c" dependencies = [ "endi", "enumflags2", @@ -9218,14 +9221,14 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "5.7.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e" +checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006" dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.107", "zvariant_utils", ] @@ -9238,6 +9241,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.106", + "syn 2.0.107", "winnow 0.7.13", ] From be30cd178feb3a956bdccd3c7db9ae564514cd22 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 20 Oct 2025 17:07:53 -0500 Subject: [PATCH 51/58] update backend location --- fly.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fly.toml b/fly.toml index 94214340a8..8e62804218 100644 --- a/fly.toml +++ b/fly.toml @@ -38,6 +38,4 @@ kill_timeout = '300s' soft_limit = 20 [[vm]] - memory = '2gb' - cpu_kind = 'shared' - cpus = 8 + size = 'performance-4x' From dca2b434b00b5014bdfa3c206d9c7b2b71c77d5b Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Mon, 20 Oct 2025 17:11:18 -0500 Subject: [PATCH 52/58] update location in playground urls --- fly.toml | 10 +++++----- packages/docsite/src/components/playground.rs | 4 ++-- packages/playground/runner/src/main.rs | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fly.toml b/fly.toml index 8e62804218..85b34b9a8c 100644 --- a/fly.toml +++ b/fly.toml @@ -1,12 +1,12 @@ -# fly.toml app configuration file generated for docsite-playground on 2025-02-04T15:44:00-08:00 +# fly.toml app configuration file generated for docsite-playground-red-wildflower-209-red-wildflower-209 on 2025-10-20T16:41:20-05:00 # # See https://fly.io/docs/reference/configuration/ for information about how to use this file. # -app = 'docsite-playground' -primary_region = 'lax' +app = 'docsite-playground-red-wildflower-209' +primary_region = 'sjc' kill_signal = 'SIGINT' -kill_timeout = '300s' +kill_timeout = '5m0s' [build] @@ -38,4 +38,4 @@ kill_timeout = '300s' soft_limit = 20 [[vm]] - size = 'performance-4x' + size = 'performance-2x' diff --git a/packages/docsite/src/components/playground.rs b/packages/docsite/src/components/playground.rs index 715ebebd67..ad123b44b1 100644 --- a/packages/docsite/src/components/playground.rs +++ b/packages/docsite/src/components/playground.rs @@ -10,8 +10,8 @@ const URLS: PlaygroundUrls = PlaygroundUrls { #[cfg(feature = "production")] const URLS: PlaygroundUrls = PlaygroundUrls { - socket: "wss://docsite-playground.fly.dev/ws", - server: "https://docsite-playground.fly.dev", + socket: "wss://docsite-playground-red-wildflower-209.fly.dev/ws", + server: "https://docsite-playground-red-wildflower-209.fly.dev", location: "https://dioxuslabs.com/playground", }; diff --git a/packages/playground/runner/src/main.rs b/packages/playground/runner/src/main.rs index ab7ac3e02b..7d25883c20 100644 --- a/packages/playground/runner/src/main.rs +++ b/packages/playground/runner/src/main.rs @@ -13,8 +13,8 @@ const URLS: PlaygroundUrls = PlaygroundUrls { #[cfg(feature = "real-server")] const URLS: PlaygroundUrls = PlaygroundUrls { - socket: "wss://docsite-playground.fly.dev/ws", - server: "https://docsite-playground.fly.dev", + socket: "wss://docsite-playground-red-wildflower-209.fly.dev/ws", + server: "https://docsite-playground-red-wildflower-209.fly.dev", location: "https://dioxuslabs.com/playground", }; From 11980f625f681243adc2b4df782da1b464458f82 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 21 Oct 2025 11:39:09 -0500 Subject: [PATCH 53/58] binstall the CLI --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 5d137e9d49..6feb9e6816 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /app FROM chef AS planner COPY . . -RUN cargo install dioxus-cli --git https://github.com/ealmloff/dioxus --branch cli-playground --root /.cargo +RUN cargo binstall dioxus-cli@0.7.0-alpha.3 -y --root /.cargo RUN cargo chef prepare --recipe-path recipe.json --bin server # Builder From 7c0a0abed77b1de8d8d4bf2ad68cb9c58826bd44 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 21 Oct 2025 11:50:24 -0500 Subject: [PATCH 54/58] bump dioxus version --- Dockerfile | 2 +- packages/playground/server/src/build/builder.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6feb9e6816..205fc4760c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /app FROM chef AS planner COPY . . -RUN cargo binstall dioxus-cli@0.7.0-alpha.3 -y --root /.cargo +RUN cargo install dioxus-cli --git https://github.com/DioxusLabs/dioxus --root /.cargo RUN cargo chef prepare --recipe-path recipe.json --bin server # Builder diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index 12956affbc..a8544b5b35 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -43,7 +43,7 @@ impl Builder { pub fn update_component_library(&mut self) -> Result<(), BuildError> { // Update the component library cache let update_status = Command::new("dx") - .arg("component") + .arg("components") .arg("update") .current_dir(&self.env.build_template_path) .stdout(Stdio::null()) @@ -54,7 +54,7 @@ impl Builder { } // Add all components to the template project let status = Command::new("dx") - .arg("component") + .arg("components") .arg("add") .arg("--all") .arg("--force") From df9d655db415dcd27fa05ffa0df21aac7b3d230c Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 27 Oct 2025 15:38:22 -0700 Subject: [PATCH 55/58] inline the sdk functions we need --- Cargo.lock | 1 + Cargo.toml | 4 +- packages/playground/playground/Cargo.toml | 6 +- .../playground/playground/src/debounce.rs | 315 ++++++++++++++++++ .../playground/src/editor/monaco.rs | 3 +- packages/playground/playground/src/lib.rs | 21 +- packages/playground/playground/src/theme.rs | 226 +++++++++++++ 7 files changed, 564 insertions(+), 12 deletions(-) create mode 100644 packages/playground/playground/src/debounce.rs create mode 100644 packages/playground/playground/src/theme.rs diff --git a/Cargo.lock b/Cargo.lock index 177f0a26da..26d5234e9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2049,6 +2049,7 @@ dependencies = [ "tracing", "uuid", "wasm-bindgen", + "web-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 083e07fa8c..cb7f74d3c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,8 +83,8 @@ dioxus-dx-wire-format = "0.7.0-rc.3" dioxus-devtools-types = "0.7.0-rc.3" dioxus-logger = "0.7.0-rc.3" -# 3rd-party dioxus -dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +# # 3rd-party dioxus +# dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } getrandom = { version = "0.2" } serde = { version = "1.0.215", features = ["derive"] } diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index b789194439..3a8db673e0 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -16,7 +16,7 @@ thiserror = { workspace = true } # Dioxus dioxus = { workspace = true, features = ["web", "router"] } dioxus-document = { workspace = true } -dioxus-sdk = { workspace = true, features = ["util", "time", "window"] } +# dioxus-sdk = { workspace = true, features = ["util", "time", "window"] } # Hot reload / Paste as RSX dioxus-core = { workspace = true } @@ -43,5 +43,9 @@ example-projects = { workspace = true } dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false } tracing = "0.1.41" +[target.'cfg(target_family = "wasm")'.dependencies] +web-sys = { version = "0.3.60", features = ["Window", "MediaQueryList"] } + + [target.'cfg(target_arch = "wasm32")'.dependencies] # dioxus-sdk = { workspace = true, default-features = false, features = ["system_theme", "window_size", "timing",] } diff --git a/packages/playground/playground/src/debounce.rs b/packages/playground/playground/src/debounce.rs new file mode 100644 index 0000000000..e8b3b5590f --- /dev/null +++ b/packages/playground/playground/src/debounce.rs @@ -0,0 +1,315 @@ +// use crate::{use_timeout, TimeoutHandle, UseTimeout}; +use dioxus::{dioxus_core::SpawnIfAsync, hooks::use_signal, prelude::WritableExt, signals::Signal}; +use std::time::Duration; + +/// The interface for calling a debounce. +/// +/// See [`use_debounce`] for more information. +#[derive(Clone, Copy, PartialEq)] +pub struct UseDebounce { + current_handle: Signal>, + timeout: UseTimeout, +} + +impl UseDebounce { + /// Start the debounce countdown, resetting it if already started. + pub fn action(&mut self, args: Args) { + self.cancel(); + self.current_handle.set(Some(self.timeout.action(args))); + } + + /// Cancel the debounce action. + pub fn cancel(&mut self) { + if let Some(handle) = self.current_handle.take() { + handle.cancel(); + } + } +} + +/// A hook for allowing a function to be called only after a provided [`Duration`] has passed. +/// +/// Once the [`UseDebounce::action`] method is called, a timer will start counting down until +/// the callback is ran. If the [`UseDebounce::action`] method is called again, the timer will restart. +/// +/// # Examples +/// +/// Example of using a debounce: +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::use_debounce; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// // Create a two second debounce. +/// // This will print "ran" after two seconds since the last action call. +/// let mut debounce = use_debounce(Duration::from_secs(2), |_| println!("ran")); +/// +/// rsx! { +/// button { +/// onclick: move |_| { +/// // Call the debounce. +/// debounce.action(()); +/// }, +/// "Click!" +/// } +/// } +/// } +/// ``` +/// +/// #### Cancelling A Debounce +/// If you need to cancel the currently active debounce, you can call [`UseDebounce::cancel`]: +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::use_debounce; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// let mut debounce = use_debounce(Duration::from_secs(5), |_| println!("ran")); +/// +/// rsx! { +/// button { +/// // Start the debounce on click. +/// onclick: move |_| debounce.action(()), +/// "Action!" +/// } +/// button { +/// // Cancel the debounce on click. +/// onclick: move |_| debounce.cancel(), +/// "Cancel!" +/// } +/// } +/// } +/// ``` +/// +/// ### Async Debounce +/// Debounces can accept an async callback: +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::use_debounce; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// // Create a two second debounce that uses some async/await. +/// let mut debounce = use_debounce(Duration::from_secs(2), |_| async { +/// println!("debounce called!"); +/// tokio::time::sleep(Duration::from_secs(2)).await; +/// println!("after async"); +/// }); +/// +/// rsx! { +/// button { +/// onclick: move |_| { +/// // Call the debounce. +/// debounce.action(()); +/// }, +/// "Click!" +/// } +/// } +/// } +/// ``` +pub fn use_debounce, Marker>( + duration: Duration, + callback: impl FnMut(Args) -> MaybeAsync + 'static, +) -> UseDebounce { + let timeout = use_timeout(duration, callback); + let current_handle = use_signal(|| None); + + UseDebounce { + timeout, + current_handle, + } +} + +use dioxus::{ + core::Task, + // dioxus_core::SpawnIfAsync, + prelude::{spawn, use_hook, Callback}, + // signals::Signal, +}; +use futures::{channel::mpsc, SinkExt, StreamExt}; +// use std::time::Duration; + +/// The interface to a timeout. +/// +/// This is used to trigger the timeout with [`UseTimeout::action`]. +/// +/// See [`use_timeout`] for more information. +pub struct UseTimeout { + duration: Duration, + sender: Signal>, +} + +impl UseTimeout { + /// Trigger the timeout. + /// + /// If no arguments are desired, use the [`unit`] type. + /// See [`use_timeout`] for more information. + pub fn action(&self, args: Args) -> TimeoutHandle { + let mut sender = (self.sender)(); + let duration = self.duration; + + let handle = spawn(async move { + // #[cfg(not(target_family = "wasm"))] + // tokio::time::sleep(duration).await; + + #[cfg(target_family = "wasm")] + gloo_timers::future::sleep(duration).await; + + // If this errors then the timeout was likely dropped. + let _ = sender.send(args).await; + }); + + TimeoutHandle { handle } + } +} + +impl Clone for UseTimeout { + fn clone(&self) -> Self { + *self + } +} +impl Copy for UseTimeout {} +impl PartialEq for UseTimeout { + fn eq(&self, other: &Self) -> bool { + self.duration == other.duration && self.sender == other.sender + } +} + +/// A handle to a pending timeout. +/// +/// A handle to a running timeout triggered with [`UseTimeout::action`]. +/// This handle allows you to cancel the timeout from triggering with [`TimeoutHandle::cancel`] +/// +/// See [`use_timeout`] for more information. +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct TimeoutHandle { + handle: Task, +} + +impl TimeoutHandle { + /// Cancel the timeout associated with this handle. + pub fn cancel(self) { + self.handle.cancel(); + } +} + +/// A hook to run a callback after a period of time. +/// +/// Timeouts allow you to trigger a callback that occurs after a period of time. Unlike a debounce, a timeout will not +/// reset it's timer when triggered again. Instead, calling a timeout while it is already running will start another instance +/// to run the callback after the provided period. +/// +/// This hook is similar to the web [setTimeout()](https://developer.mozilla.org/en-US/docs/Web/API/Window/setTimeout) API. +/// +/// # Examples +/// +/// Example of using a timeout: +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::use_timeout; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// // Create a timeout for two seconds. +/// // Once triggered, this timeout will print "timeout called" after two seconds. +/// let timeout = use_timeout(Duration::from_secs(2), |()| println!("timeout called")); +/// +/// rsx! { +/// button { +/// onclick: move |_| { +/// // Trigger the timeout. +/// timeout.action(()); +/// }, +/// "Click!" +/// } +/// } +/// } +/// ``` +/// +/// #### Cancelling Timeouts +/// Example of cancelling a timeout. This is the equivalent of a debounce. +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::{use_timeout, TimeoutHandle}; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// let mut current_timeout: Signal> = use_signal(|| None); +/// let timeout = use_timeout(Duration::from_secs(2), move |()| { +/// current_timeout.set(None); +/// println!("timeout called"); +/// }); +/// +/// rsx! { +/// button { +/// onclick: move |_| { +/// // Cancel any currently running timeouts. +/// if let Some(handle) = *current_timeout.read() { +/// handle.cancel(); +/// } +/// +/// // Trigger the timeout. +/// let handle = timeout.action(()); +/// current_timeout.set(Some(handle)); +/// }, +/// "Click!" +/// } +/// } +/// } +/// ``` +/// +/// #### Async Timeouts +/// Timeouts can accept an async callback: +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_time::use_timeout; +/// use std::time::Duration; +/// +/// #[component] +/// fn App() -> Element { +/// // Create a timeout for two seconds. +/// // We use an async sleep to wait an even longer duration after the timeout is called. +/// let timeout = use_timeout(Duration::from_secs(2), |()| async { +/// println!("Timeout after two total seconds."); +/// tokio::time::sleep(Duration::from_secs(2)).await; +/// println!("Timeout after four total seconds."); +/// }); +/// +/// rsx! { +/// button { +/// onclick: move |_| { +/// // Trigger the timeout. +/// timeout.action(()); +/// }, +/// "Click!" +/// } +/// } +/// } +/// ``` +pub fn use_timeout, Marker>( + duration: Duration, + callback: impl FnMut(Args) -> MaybeAsync + 'static, +) -> UseTimeout { + use_hook(|| { + let callback = Callback::new(callback); + let (sender, mut receiver) = mpsc::unbounded(); + + spawn(async move { + loop { + if let Some(args) = receiver.next().await { + callback.call(args); + } + } + }); + + UseTimeout { + duration, + sender: Signal::new(sender), + } + }) +} diff --git a/packages/playground/playground/src/editor/monaco.rs b/packages/playground/playground/src/editor/monaco.rs index 6dd54e83c0..0fee297397 100644 --- a/packages/playground/playground/src/editor/monaco.rs +++ b/packages/playground/playground/src/editor/monaco.rs @@ -1,7 +1,8 @@ use crate::hotreload::HotReload; use crate::hotreload::HotReloadStoreImplExt; +use crate::theme::Theme; use dioxus::prelude::*; -use dioxus_sdk::window::theme::Theme; +// use dioxus_sdk::window::theme::Theme; use model::{CargoDiagnostic, CargoLevel}; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; diff --git a/packages/playground/playground/src/lib.rs b/packages/playground/playground/src/lib.rs index 0f575e6efe..1cc8b7570c 100644 --- a/packages/playground/playground/src/lib.rs +++ b/packages/playground/playground/src/lib.rs @@ -3,13 +3,18 @@ use components::icons::Warning; use dioxus::logger::tracing::error; use dioxus::prelude::*; use dioxus_document::Link; -use dioxus_sdk::time::use_debounce; +// use dioxus_sdk::time::use_debounce; use editor::monaco::{self, monaco_loader_src, set_monaco_markers}; use hotreload::{attempt_hot_reload, HotReload}; use model::{api::ApiClient, AppError, Project, SocketError}; use std::time::Duration; -use dioxus_sdk::window::theme::{use_system_theme, Theme}; +mod theme; +use theme::{get_theme, use_system_theme, Theme}; +mod debounce; +use debounce::use_debounce; + +// use dioxus_sdk::window::theme::{use_system_theme, Theme}; use crate::{ build::{BuildStateStoreExt, BuildStateStoreImplExt}, @@ -99,11 +104,11 @@ pub fn Playground( // Handle setting diagnostics based on build state. use_effect(move || set_monaco_markers(build.diagnostics())); - // Themes - let system_theme = use_system_theme(); - use_effect(move || { - editor::monaco::set_theme(system_theme().unwrap_or(Theme::Light)); - }); + // // Themes + // let system_theme = use_system_theme(); + // use_effect(move || { + // editor::monaco::set_theme(system_theme().unwrap_or(Theme::Light)); + // }); // Handle starting a build. let on_rebuild = use_callback(move |_| { @@ -162,7 +167,7 @@ pub fn Playground( onload: move |_| { monaco::on_monaco_load( MONACO_FOLDER, - system_theme().unwrap_or(Theme::Light), + get_theme().unwrap_or(Theme::Light), &project.read().contents(), hot_reload, monaco_ready, diff --git a/packages/playground/playground/src/theme.rs b/packages/playground/playground/src/theme.rs new file mode 100644 index 0000000000..ca0a0e6f86 --- /dev/null +++ b/packages/playground/playground/src/theme.rs @@ -0,0 +1,226 @@ +//! Theme utilities. +//! +//! Access the system's theme to use for common tasks such as automatically setting your app styling. +//! +//! Most apps will need to choose a default theme in the event of an error. +//! We recommend using either [`Result::unwrap_or`] or [`Result::unwrap_or_default`] to do this. +//! +//! #### Platform Support +//! Theme is available for Web, Windows, & Mac. Linux is unsupported and Android/iOS has not been tested. +//! +//! # Examples +//! An example of using the theme to determine which class to use. +//! ```rust +//! use dioxus::prelude::*; +//! use dioxus_window::theme::{use_system_theme, Theme}; +//! +//! #[component] +//! fn App() -> Element { +//! let theme = use_system_theme(); +//! +//! // Default to a light theme in the event of an error. +//! let class = match theme().unwrap_or(Theme::Light) { +//! Theme::Light => "bg-light", +//! Theme::Dark => "bg-dark", +//! }; +//! +//! rsx! { +//! div { +//! class: "{class}", +//! "the current theme is: {theme().unwrap_or(Theme::Light)}" +//! } +//! } +//! } +//! ``` +use dioxus::{core::provide_root_context, prelude::*}; +use std::{error::Error, fmt::Display}; + +/// A color theme. +/// +/// For any themes other than `light` and `dark`, a [`ThemeError::UnknownTheme`] will be returned. +/// We may be able to support custom themes in the future. +#[derive(Debug, Clone, Copy, PartialEq, Default)] +pub enum Theme { + /// A light theme, better in direct sunlight. + #[default] + Light, + /// A dark theme, better for the night owls. + Dark, +} + +impl Display for Theme { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Light => write!(f, "light"), + Self::Dark => write!(f, "dark"), + } + } +} + +/// Possible theme errors. +#[derive(Debug, Clone, PartialEq)] +pub enum ThemeError { + /// Theme is not supported on this platform. + Unsupported, + /// Failed to get the system theme. + CheckFailed, + /// System returned an unknown theme. + UnknownTheme, +} + +impl Error for ThemeError {} +impl Display for ThemeError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Self::Unsupported => write!(f, "the current platform is not supported"), + Self::CheckFailed => write!( + f, + "the system returned an error while checking the color theme" + ), + Self::UnknownTheme => write!( + f, + "the system provided a theme other than `light` or `dark`" + ), + } + } +} + +type ThemeResult = Result; + +/// Get a signal to the system theme. +/// +/// On first run, the result will be [`ThemeError::Unsupported`]. This is to prevent hydration from failing. +/// After the client runs, the theme will be tracked and updated with accurate values. +/// +/// # Examples +/// +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_window::theme::{use_system_theme, Theme}; +/// +/// #[component] +/// fn App() -> Element { +/// let theme = use_system_theme(); +/// +/// rsx! { +/// p { +/// "the current theme is: {theme().unwrap_or(Theme::Light)}" +/// } +/// } +/// } +/// ``` +pub fn use_system_theme() -> ReadSignal { + let mut system_theme = match try_use_context::>() { + Some(s) => s, + // This should only run once. + None => { + let signal = Signal::new_in_scope(Err(ThemeError::Unsupported), ScopeId::ROOT); + provide_root_context(signal) + } + }; + + // Only start the listener on the client. + use_effect(move || { + system_theme.set(get_theme()); + + #[cfg(target_arch = "wasm32")] + listen(system_theme); + }); + + use_hook(|| ReadSignal::new(system_theme)) +} + +// The listener implementation for wasm targets. +#[cfg(target_arch = "wasm32")] +fn listen(mut theme: Signal) { + use wasm_bindgen::{closure::Closure, JsCast}; + use web_sys::MediaQueryList; + + let Some(window) = web_sys::window() else { + theme.set(Err(ThemeError::Unsupported)); + return; + }; + + // Get the media query + let Ok(query) = window.match_media("(prefers-color-scheme: dark)") else { + theme.set(Err(ThemeError::CheckFailed)); + return; + }; + + let Some(query) = query else { + theme.set(Err(ThemeError::UnknownTheme)); + return; + }; + + // Listener that is called when the media query changes. + // https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/change_event + let listener = Closure::wrap(Box::new(move |query: MediaQueryList| { + match query.matches() { + true => theme.set(Ok(Theme::Dark)), + false => theme.set(Ok(Theme::Light)), + }; + }) as Box); + + let cb = listener.as_ref().clone(); + listener.forget(); + query.set_onchange(Some(cb.unchecked_ref())); +} + +/// Get the current theme. +/// +/// +/// **Note** +/// +/// This function will cause hydration to fail if not used inside an effect, task, or event handler. +/// +/// # Examples +/// +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_window::theme::{Theme, get_theme}; +/// +/// #[component] +/// fn App() -> Element { +/// let theme = use_signal(get_theme); +/// +/// let class_name = match theme().unwrap_or(Theme::Light) { +/// Theme::Dark => "dark-theme", +/// Theme::Light => "light-theme", +/// }; +/// +/// rsx! { +/// div { +/// style: "width: 100px; height: 100px;", +/// class: "{class_name}", +/// } +/// } +/// } +/// ``` +pub fn get_theme() -> ThemeResult { + #[cfg(target_arch = "wasm32")] + return get_theme_platform(); + + #[cfg(not(target_arch = "wasm32"))] + return Ok(Theme::Light); +} + +// The wasm implementation to get the system theme. +#[cfg(target_arch = "wasm32")] +fn get_theme_platform() -> ThemeResult { + let Some(window) = web_sys::window() else { + return Err(ThemeError::Unsupported); + }; + + // Check the color theme with a media query + let Some(query) = window + .match_media("(prefers-color-scheme: dark)") + .or(Err(ThemeError::CheckFailed))? + else { + return Err(ThemeError::UnknownTheme); + }; + + match query.matches() { + true => Ok(Theme::Dark), + false => Ok(Theme::Light), + } +} From a4f27fa42e5c8a413c65e020b08d6e5ee1c3ac51 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 27 Oct 2025 15:38:33 -0700 Subject: [PATCH 56/58] updte lock --- Cargo.lock | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 26d5234e9c..441a9d5929 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2033,7 +2033,6 @@ dependencies = [ "dioxus-rsx", "dioxus-rsx-hotreload", "dioxus-rsx-rosetta", - "dioxus-sdk", "example-projects", "futures", "gloo-net", @@ -2147,16 +2146,6 @@ dependencies = [ "syn 2.0.108", ] -[[package]] -name = "dioxus-sdk" -version = "0.7.0-rc.3" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#4b21134c3950d219a6e42ba33b6ba4bda97c062b" -dependencies = [ - "dioxus-time", - "dioxus-util", - "dioxus-window", -] - [[package]] name = "dioxus-search" version = "0.1.0" @@ -2320,15 +2309,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "dioxus-util" -version = "0.7.0-rc.3" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#4b21134c3950d219a6e42ba33b6ba4bda97c062b" -dependencies = [ - "dioxus", - "serde", -] - [[package]] name = "dioxus-web" version = "0.7.0-rc.3" @@ -2363,18 +2343,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "dioxus-window" -version = "0.7.0-rc.3" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#4b21134c3950d219a6e42ba33b6ba4bda97c062b" -dependencies = [ - "dioxus", - "dioxus-config-macro", - "dioxus-desktop", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "dioxus_docs_site" version = "0.0.0" From 92e01c53600f259c93d9a12048eb0a0f2e815c9a Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Mon, 27 Oct 2025 15:40:08 -0700 Subject: [PATCH 57/58] compile err --- Cargo.lock | 1 + packages/playground/playground/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 441a9d5929..fca61d6335 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2036,6 +2036,7 @@ dependencies = [ "example-projects", "futures", "gloo-net", + "gloo-timers", "gloo-utils", "miniz_oxide", "model", diff --git a/packages/playground/playground/Cargo.toml b/packages/playground/playground/Cargo.toml index 3a8db673e0..5130f3c621 100644 --- a/packages/playground/playground/Cargo.toml +++ b/packages/playground/playground/Cargo.toml @@ -31,6 +31,7 @@ dioxus-rsx-rosetta = { workspace = true } dioxus-autofmt = { workspace = true } gloo-utils = { workspace = true } +gloo-timers = { version = "0.3.0" } wasm-bindgen = { version = "0.2.99", features = ["serde-serialize"] } miniz_oxide = { version = "0.8.0", features = ["std"] } base64 = "0.22.1" From 8f3819bf76e8400b3dd33d6082ea70446e09179e Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 28 Oct 2025 13:59:54 -0500 Subject: [PATCH 58/58] Fix running the server from the root of the workspace --- .../playground/server/src/build/builder.rs | 39 ++++++++++++------- .../playground/server/src/build/watcher.rs | 3 -- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/packages/playground/server/src/build/builder.rs b/packages/playground/server/src/build/builder.rs index a8544b5b35..8c8df1ea9d 100644 --- a/packages/playground/server/src/build/builder.rs +++ b/packages/playground/server/src/build/builder.rs @@ -40,28 +40,30 @@ impl Builder { } /// Make sure the components are initialized - pub fn update_component_library(&mut self) -> Result<(), BuildError> { + pub async fn update_component_library(build_template_path: &Path) -> Result<(), BuildError> { // Update the component library cache - let update_status = Command::new("dx") + let update_status = tokio::process::Command::new("dx") .arg("components") .arg("update") - .current_dir(&self.env.build_template_path) + .current_dir(build_template_path) .stdout(Stdio::null()) .stderr(Stdio::null()) - .status()?; + .status() + .await?; if !update_status.success() { return Err(BuildError::DxFailed(update_status.code())); } // Add all components to the template project - let status = Command::new("dx") + let status = tokio::process::Command::new("dx") .arg("components") .arg("add") - .arg("--all") + .arg("calendar") .arg("--force") - .current_dir(&self.env.build_template_path) + .current_dir(build_template_path) .stdout(Stdio::null()) .stderr(Stdio::null()) - .status()?; + .status() + .await?; if !status.success() { return Err(BuildError::DxFailed(status.code())); } @@ -145,9 +147,9 @@ async fn setup_template( request: &BuildRequest, patch: bool, ) -> Result<(), BuildError> { - let snippets_from_copy = [ - template_path.join("snippets/Cargo.toml"), - template_path.join("snippets/Dioxus.toml"), + let snippets_templates = [ + include_str!("../../template/snippets/Cargo.toml"), + include_str!("../../template/snippets/Dioxus.toml"), ]; // New locations @@ -157,9 +159,8 @@ async fn setup_template( ]; // Enumerate over a list of paths to copy and copies them to the new location while modifying any template strings. - for (i, path) in snippets_from_copy.iter().enumerate() { + for (i, contents) in snippets_templates.iter().enumerate() { let new_path = &snippets_to_copy[i]; - let contents = fs::read_to_string(path).await?; let contents = contents.replace( BUILD_ID_TEMPLATE, &request @@ -171,6 +172,12 @@ async fn setup_template( fs::write(new_path, contents).await?; } + // Create the src directory if it doesn't exist + let src_path = template_path.join("src"); + if !src_path.exists() { + fs::create_dir_all(&src_path).await?; + } + // Write the user's code to main.rs fs::write( template_path.join("src/main.rs"), @@ -178,6 +185,12 @@ async fn setup_template( ) .await?; + // If the component library doesn't exist, create it + let component_folder_path = template_path.join("src").join("components"); + if !component_folder_path.exists() { + Builder::update_component_library(template_path).await?; + } + Ok(()) } diff --git a/packages/playground/server/src/build/watcher.rs b/packages/playground/server/src/build/watcher.rs index 641489e063..81d8392d3b 100644 --- a/packages/playground/server/src/build/watcher.rs +++ b/packages/playground/server/src/build/watcher.rs @@ -23,9 +23,6 @@ pub fn start_build_watcher( let (tx, mut rx) = mpsc::unbounded_channel(); let mut builder = Builder::new(env, is_building); - if let Err(err) = builder.update_component_library() { - tracing::error!("failed to update component library: {err}"); - } tokio::spawn(async move { let mut pending_builds = VecDeque::new();