#![cfg(feature = "hot_reload")] //! This module contains hotreloading logic for rsx. //! //! There's a few details that I wish we could've gotten right but we can revisit later: //! //! - Empty rsx! blocks are written as `None` - it would be nice to be able to hot reload them //! //! - The byte index of the template is not the same as the byte index of the original template //! this forces us to make up IDs on the fly. We should just find an ID naming scheme, but that //! struggles when you have nested rsx! calls since file:line:col is the same for all expanded rsx! //! //! - There's lots of linear scans //! //! - Expanding an if chain is not possible - only its contents can be hot reloaded //! //! - Components that don't start with children can't be hotreloaded - IE going from `Comp {}` to `Comp { "foo" }` //! is not possible. We could in theory allow this by seeding all Components with a `children` field. //! //! - Cross-templates hot reloading is not possible - multiple templates don't share the dynamic nodes. //! This would require changes in core to work, I imagine. //! //! Future work //! //! - We've proven that binary patching is feasible but has a longer path to stabilization for all platforms. //! Binary patching is pretty quick, actually, and *might* remove the need to literal hotreloading. //! However, you could imagine a scenario where literal hotreloading would be useful without the //! compiler in the loop. Ideally we can slash most of this code once patching is stable. //! //! - We could also allow adding arbitrary nodes/attributes at runtime. The template system doesn't //! quite support that, unfortunately, since the number of dynamic nodes and attributes is baked into //! the template, but if that changed we'd be okay. use crate::{innerlude::*, scoring::score_dynamic_node}; use crate::{scoring::score_attribute, HotReloadingContext}; use dioxus_core::{internal::HotReloadLiteral, Template}; use std::collections::HashMap; /// The mapping of a node relative to the root of its containing template /// /// IE [0, 1] would be the location of the h3 node in this template: /// ```rust, ignore /// rsx! { /// div { /// h1 { "title" } /// h3 { class: "{class}", "Hi" } /// } /// } /// ``` type NodePath = Vec; /// The mapping of an attribute relative to the root of its containing template /// Order doesn't matter for attributes, you can render them in any order on a given node.a /// /// IE [0, 1] would be the location of the `class` attribute on this template: /// ```rust, ignore /// rsx! { /// div { /// h1 { "title" } /// h3 { class: "{class}", "Hi" } /// } /// } /// ``` type AttributePath = Vec; /// A result of hot reloading /// /// This contains information about what has changed so the hotreloader can apply the right changes #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[non_exhaustive] #[derive(Debug, PartialEq, Clone)] pub struct HotReloadedTemplate { /// List of inner templates that changed (nested blocks like for/if/component bodies) pub templates: Vec