hello world example working
This commit is contained in:
1 parent
3865f44081
commit
4013341b6c
22 files changed
+159
-176
No files matched your search
@@ -17,7 +17,6 @@ proc-macro2 = { version = "1.0" }
|
|||||||
quote = "1.0"
|
quote = "1.0"
|
||||||
syn = { version = "2.0", features = ["full", "extra-traits"] }
|
syn = { version = "2.0", features = ["full", "extra-traits"] }
|
||||||
dioxus-rsx = { workspace = true }
|
dioxus-rsx = { workspace = true }
|
||||||
dioxus-core = { workspace = true }
|
|
||||||
constcat = "0.3.0"
|
constcat = "0.3.0"
|
||||||
prettyplease = "0.2.15"
|
prettyplease = "0.2.15"
|
||||||
|
|
||||||
|
|||||||
@@ -147,9 +147,7 @@ pub mod utils;
|
|||||||
|
|
||||||
pub use utils::DeserializerArgs;
|
pub use utils::DeserializerArgs;
|
||||||
pub use utils::DeserializerOutput;
|
pub use utils::DeserializerOutput;
|
||||||
pub use utils::TypeHelper;
|
|
||||||
|
|
||||||
use dioxus_core::{Element, Scope};
|
|
||||||
use syn::parse::{Parse, ParseStream};
|
use syn::parse::{Parse, ParseStream};
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::*;
|
use syn::*;
|
||||||
@@ -167,12 +165,6 @@ pub struct ComponentBody {
|
|||||||
/// Keep this in mind when creating deserializers, because you often might want to ignore it.
|
/// Keep this in mind when creating deserializers, because you often might want to ignore it.
|
||||||
/// That might be annoying, but it would be bad design for this kind of struct to not be parsable from itself.
|
/// That might be annoying, but it would be bad design for this kind of struct to not be parsable from itself.
|
||||||
pub item_fn: ItemFn,
|
pub item_fn: ItemFn,
|
||||||
/// Parsing tries to ensure that this argument will be a [`Scope`].
|
|
||||||
/// **However, macros have limitations that prevent this from always working,
|
|
||||||
/// so don't take this for granted!**
|
|
||||||
pub cx_arg: FnArg,
|
|
||||||
/// The pattern (name) and type of the context argument.
|
|
||||||
pub cx_pat_type: PatType,
|
|
||||||
/// If the function has any arguments other than the context.
|
/// If the function has any arguments other than the context.
|
||||||
pub has_extra_args: bool,
|
pub has_extra_args: bool,
|
||||||
}
|
}
|
||||||
@@ -192,31 +184,8 @@ impl ComponentBody {
|
|||||||
impl Parse for ComponentBody {
|
impl Parse for ComponentBody {
|
||||||
fn parse(input: ParseStream) -> Result<Self> {
|
fn parse(input: ParseStream) -> Result<Self> {
|
||||||
let item_fn: ItemFn = input.parse()?;
|
let item_fn: ItemFn = input.parse()?;
|
||||||
let scope_type_path = Scope::get_path_string();
|
|
||||||
|
|
||||||
let (cx_arg, cx_pat_type) = if let Some(first_arg) = item_fn.sig.inputs.first() {
|
let element_type_path = "::dioxus::core::Element";
|
||||||
let incorrect_first_arg_err = Err(Error::new(
|
|
||||||
first_arg.span(),
|
|
||||||
format!("First argument must be a <{}>", scope_type_path),
|
|
||||||
));
|
|
||||||
|
|
||||||
match first_arg.to_owned() {
|
|
||||||
FnArg::Receiver(_) => {
|
|
||||||
return incorrect_first_arg_err;
|
|
||||||
}
|
|
||||||
FnArg::Typed(f) => (first_arg.to_owned(), f),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return Err(Error::new(
|
|
||||||
item_fn.sig.ident.span(), // Or maybe just item_f.sig.span()?
|
|
||||||
format!(
|
|
||||||
"Must have at least one argument that's a <{}>",
|
|
||||||
scope_type_path
|
|
||||||
),
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
let element_type_path = Element::get_path_string();
|
|
||||||
|
|
||||||
if item_fn.sig.output == ReturnType::Default {
|
if item_fn.sig.output == ReturnType::Default {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
@@ -229,8 +198,6 @@ impl Parse for ComponentBody {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
item_fn,
|
item_fn,
|
||||||
cx_arg,
|
|
||||||
cx_pat_type,
|
|
||||||
has_extra_args,
|
has_extra_args,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use crate::component_body::ComponentBody;
|
use crate::component_body::ComponentBody;
|
||||||
use dioxus_core::{Element, Scope};
|
|
||||||
use quote::ToTokens;
|
use quote::ToTokens;
|
||||||
use syn::{parse_quote, Path};
|
use syn::{parse_quote, Path};
|
||||||
|
|
||||||
@@ -36,22 +35,3 @@ where
|
|||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
fn to_output(&self, component_body: &ComponentBody) -> syn::Result<TOutput>;
|
fn to_output(&self, component_body: &ComponentBody) -> syn::Result<TOutput>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeHelper {
|
|
||||||
fn get_path() -> Path;
|
|
||||||
fn get_path_string() -> String {
|
|
||||||
Self::get_path().to_token_stream().to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeHelper for Scope<'a> {
|
|
||||||
fn get_path() -> Path {
|
|
||||||
parse_quote!(::dioxus::core::Scope)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> TypeHelper for Element<'a> {
|
|
||||||
fn get_path() -> Path {
|
|
||||||
parse_quote!(::dioxus::core::Element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ To ignore this check, pass the \"",
|
|||||||
|
|
||||||
const INNER_FN_NAME: &str = "__dx_inner_comp";
|
const INNER_FN_NAME: &str = "__dx_inner_comp";
|
||||||
|
|
||||||
fn get_out_comp_fn(orig_comp_fn: &ItemFn, cx_pat: &Pat) -> ItemFn {
|
fn get_out_comp_fn(orig_comp_fn: &ItemFn) -> ItemFn {
|
||||||
let inner_comp_ident = Ident::new(INNER_FN_NAME, orig_comp_fn.sig.ident.span());
|
let inner_comp_ident = Ident::new(INNER_FN_NAME, orig_comp_fn.sig.ident.span());
|
||||||
|
|
||||||
let inner_comp_fn = ItemFn {
|
let inner_comp_fn = ItemFn {
|
||||||
@@ -34,7 +34,7 @@ fn get_out_comp_fn(orig_comp_fn: &ItemFn, cx_pat: &Pat) -> ItemFn {
|
|||||||
#[allow(clippy::inline_always)]
|
#[allow(clippy::inline_always)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#inner_comp_fn
|
#inner_comp_fn
|
||||||
#inner_comp_ident (#cx_pat)
|
#inner_comp_ident(__props)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
..orig_comp_fn.clone()
|
..orig_comp_fn.clone()
|
||||||
@@ -88,14 +88,9 @@ impl DeserializerArgs<ComponentDeserializerOutput> for ComponentDeserializerArgs
|
|||||||
|
|
||||||
impl ComponentDeserializerArgs {
|
impl ComponentDeserializerArgs {
|
||||||
fn deserialize_no_props(component_body: &ComponentBody) -> ComponentDeserializerOutput {
|
fn deserialize_no_props(component_body: &ComponentBody) -> ComponentDeserializerOutput {
|
||||||
let ComponentBody {
|
let ComponentBody { item_fn, .. } = component_body;
|
||||||
item_fn,
|
|
||||||
cx_pat_type,
|
|
||||||
..
|
|
||||||
} = component_body;
|
|
||||||
let cx_pat = &cx_pat_type.pat;
|
|
||||||
|
|
||||||
let comp_fn = get_out_comp_fn(item_fn, cx_pat);
|
let comp_fn = get_out_comp_fn(item_fn);
|
||||||
|
|
||||||
ComponentDeserializerOutput {
|
ComponentDeserializerOutput {
|
||||||
comp_fn,
|
comp_fn,
|
||||||
@@ -106,12 +101,7 @@ impl ComponentDeserializerArgs {
|
|||||||
fn deserialize_with_props(
|
fn deserialize_with_props(
|
||||||
component_body: &ComponentBody,
|
component_body: &ComponentBody,
|
||||||
) -> Result<ComponentDeserializerOutput> {
|
) -> Result<ComponentDeserializerOutput> {
|
||||||
let ComponentBody {
|
let ComponentBody { item_fn, .. } = component_body;
|
||||||
item_fn,
|
|
||||||
cx_pat_type,
|
|
||||||
..
|
|
||||||
} = component_body;
|
|
||||||
let cx_pat = &cx_pat_type.pat;
|
|
||||||
|
|
||||||
let comp_parsed = match parse2::<ComponentBody>(quote!(#item_fn)) {
|
let comp_parsed = match parse2::<ComponentBody>(quote!(#item_fn)) {
|
||||||
Ok(comp_body) => comp_body,
|
Ok(comp_body) => comp_body,
|
||||||
@@ -130,7 +120,7 @@ impl ComponentDeserializerArgs {
|
|||||||
let props_struct = inlined_props_output.props_struct;
|
let props_struct = inlined_props_output.props_struct;
|
||||||
let props_fn = inlined_props_output.comp_fn;
|
let props_fn = inlined_props_output.comp_fn;
|
||||||
|
|
||||||
let comp_fn = get_out_comp_fn(&props_fn, cx_pat);
|
let comp_fn = get_out_comp_fn(&props_fn);
|
||||||
|
|
||||||
Ok(ComponentDeserializerOutput {
|
Ok(ComponentDeserializerOutput {
|
||||||
comp_fn,
|
comp_fn,
|
||||||
|
|||||||
@@ -225,11 +225,7 @@ fn get_props_docs(fn_ident: &Ident, inputs: Vec<&FnArg>) -> Vec<Attribute> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_function(component_body: &ComponentBody) -> ItemFn {
|
fn get_function(component_body: &ComponentBody) -> ItemFn {
|
||||||
let ComponentBody {
|
let ComponentBody { item_fn, .. } = component_body;
|
||||||
item_fn,
|
|
||||||
cx_pat_type,
|
|
||||||
..
|
|
||||||
} = component_body;
|
|
||||||
let ItemFn {
|
let ItemFn {
|
||||||
attrs: fn_attrs,
|
attrs: fn_attrs,
|
||||||
vis,
|
vis,
|
||||||
@@ -246,7 +242,6 @@ fn get_function(component_body: &ComponentBody) -> ItemFn {
|
|||||||
} = sig;
|
} = sig;
|
||||||
let Generics { where_clause, .. } = generics;
|
let Generics { where_clause, .. } = generics;
|
||||||
|
|
||||||
let cx_pat = &cx_pat_type.pat;
|
|
||||||
let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
|
let struct_ident = Ident::new(&format!("{fn_ident}Props"), fn_ident.span());
|
||||||
|
|
||||||
// Skip first arg since that's the context
|
// Skip first arg since that's the context
|
||||||
@@ -298,10 +293,10 @@ fn get_function(component_body: &ComponentBody) -> ItemFn {
|
|||||||
parse_quote! {
|
parse_quote! {
|
||||||
#(#fn_attrs)*
|
#(#fn_attrs)*
|
||||||
#(#props_docs)*
|
#(#props_docs)*
|
||||||
#asyncness #vis fn #fn_ident #fn_generics (#cx_pat: Scope<#scope_lifetime #struct_ident #generics_no_bounds>) #fn_output
|
#asyncness #vis fn #fn_ident #fn_generics (__props: #struct_ident #generics_no_bounds) #fn_output
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
let #struct_ident { #(#struct_field_names),* } = &#cx_pat.props;
|
let #struct_ident { #(#struct_field_names),* } = &__props;
|
||||||
#fn_block
|
#fn_block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ impl VirtualDom {
|
|||||||
}
|
}
|
||||||
Element { .. } => {
|
Element { .. } => {
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
let id = self.write_element_root(node, idx, &mut attrs, &mut nodes, &[]);
|
let id = self.write_element_root(node, idx, &mut attrs, &mut nodes, &[], to);
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let id = self.write_element_root(
|
let id = self.write_element_root(
|
||||||
node,
|
node,
|
||||||
|
|||||||
@@ -37,11 +37,22 @@ impl Debug for ErrorBoundaryInner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait for any type that can be downcast to a concrete type and implements Debug. This is automatically implemented for all types that implement Any + Debug.
|
||||||
|
pub trait AnyDebug: Any + Debug {
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Any + Debug> AnyDebug for T {
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// An instance of an error captured by a descendant component.
|
/// An instance of an error captured by a descendant component.
|
||||||
pub struct CapturedError {
|
pub struct CapturedError {
|
||||||
/// The error captured by the error boundary
|
/// The error captured by the error boundary
|
||||||
pub error: Box<dyn Debug + 'static>,
|
pub error: Box<dyn AnyDebug + 'static>,
|
||||||
|
|
||||||
/// The backtrace of the error
|
/// The backtrace of the error
|
||||||
pub backtrace: Backtrace,
|
pub backtrace: Backtrace,
|
||||||
@@ -65,8 +76,7 @@ impl CapturedError {
|
|||||||
/// Downcast the error type into a concrete error type
|
/// Downcast the error type into a concrete error type
|
||||||
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
pub fn downcast<T: 'static>(&self) -> Option<&T> {
|
||||||
if TypeId::of::<T>() == self.error.type_id() {
|
if TypeId::of::<T>() == self.error.type_id() {
|
||||||
let raw = self.error.as_ref() as *const _ as *const T;
|
self.error.as_any().downcast_ref::<T>()
|
||||||
Some(unsafe { &*raw })
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -100,14 +110,9 @@ impl ErrorBoundary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Push an error into this Error Boundary
|
/// Push an error into this Error Boundary
|
||||||
pub fn insert_error(
|
pub fn insert_error(&self, scope: ScopeId, error: impl Debug + 'static, backtrace: Backtrace) {
|
||||||
&self,
|
|
||||||
scope: ScopeId,
|
|
||||||
error: Box<dyn Debug + 'static>,
|
|
||||||
backtrace: Backtrace,
|
|
||||||
) {
|
|
||||||
self.inner.error.replace(Some(CapturedError {
|
self.inner.error.replace(Some(CapturedError {
|
||||||
error,
|
error: Box::new(error),
|
||||||
scope,
|
scope,
|
||||||
backtrace,
|
backtrace,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use futures_util::Future;
|
use futures_util::Future;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -113,3 +115,21 @@ pub fn parent_scope() -> Option<ScopeId> {
|
|||||||
pub fn needs_update() {
|
pub fn needs_update() {
|
||||||
with_current_scope(|cx| cx.needs_update());
|
with_current_scope(|cx| cx.needs_update());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Schedule an update for the current component
|
||||||
|
///
|
||||||
|
/// Note: Unlike [`needs_update`], the function returned by this method will work outside of the dioxus runtime.
|
||||||
|
///
|
||||||
|
/// You should prefer [`schedule_update_any`] if you need to update multiple components.
|
||||||
|
pub fn schedule_update() -> Arc<dyn Fn() + Send + Sync> {
|
||||||
|
with_current_scope(|cx| cx.schedule_update()).expect("to be in a dioxus runtime")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Schedule an update for any component given its [`ScopeId`].
|
||||||
|
///
|
||||||
|
/// A component's [`ScopeId`] can be obtained from the [`current_scope_id`] method.
|
||||||
|
///
|
||||||
|
/// Note: Unlike [`needs_update`], the function returned by this method will work outside of the dioxus runtime.
|
||||||
|
pub fn schedule_update_any() -> Arc<dyn Fn(ScopeId) + Send + Sync> {
|
||||||
|
with_current_scope(|cx| cx.schedule_update_any()).expect("to be in a dioxus runtime")
|
||||||
|
}
|
||||||
@@ -74,10 +74,11 @@ pub(crate) mod innerlude {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
fc_to_builder, generation, once, vdom_is_rendering, AnyValue, Attribute, AttributeValue,
|
fc_to_builder, generation, once, schedule_update, schedule_update_any, vdom_is_rendering,
|
||||||
CapturedError, Component, DynamicNode, Element, ElementId, Event, Fragment, IntoDynNode,
|
AnyValue, Attribute, AttributeValue, CapturedError, Component, DynamicNode, Element, ElementId,
|
||||||
Mutation, MutationsVec, Properties, RenderReturn, ScopeId, Task, Template, TemplateAttribute,
|
Event, Fragment, IntoDynNode, Mutation, MutationsVec, Properties, RenderReturn, ScopeId, Task,
|
||||||
TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom, WriteMutations,
|
Template, TemplateAttribute, TemplateNode, VComponent, VNode, VPlaceholder, VText, VirtualDom,
|
||||||
|
WriteMutations,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The purpose of this module is to alleviate imports of many common types
|
/// The purpose of this module is to alleviate imports of many common types
|
||||||
@@ -87,9 +88,9 @@ pub mod prelude {
|
|||||||
pub use crate::innerlude::{
|
pub use crate::innerlude::{
|
||||||
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, generation,
|
consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, generation,
|
||||||
has_context, needs_update, once, parent_scope, provide_context, provide_root_context,
|
has_context, needs_update, once, parent_scope, provide_context, provide_root_context,
|
||||||
push_future, remove_future, spawn, spawn_forever, suspend, use_error_boundary, AnyValue,
|
push_future, remove_future, schedule_update, schedule_update_any, spawn, spawn_forever,
|
||||||
Component, Element, ErrorBoundary, Event, EventHandler, Fragment, IntoAttributeValue,
|
suspend, use_error_boundary, AnyValue, Component, Element, ErrorBoundary, Event,
|
||||||
IntoDynNode, Properties, Runtime, RuntimeGuard, ScopeId, Task, Template, TemplateAttribute,
|
EventHandler, Fragment, IntoAttributeValue, IntoDynNode, Properties, Runtime, RuntimeGuard,
|
||||||
TemplateNode, Throw, VNode, VirtualDom,
|
ScopeId, Task, Template, TemplateAttribute, TemplateNode, Throw, VNode, VirtualDom,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,7 @@ use std::{
|
|||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
future::Future,
|
future::Future,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A component's state separate from its props.
|
/// A component's state separate from its props.
|
||||||
@@ -69,6 +70,26 @@ impl ScopeContext {
|
|||||||
.expect("Scheduler to exist if scope exists");
|
.expect("Scheduler to exist if scope exists");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a subscription that schedules a future render for the reference component
|
||||||
|
///
|
||||||
|
/// ## Notice: you should prefer using [`Self::schedule_update_any`] and [`Self::scope_id`]
|
||||||
|
pub fn schedule_update(&self) -> Arc<dyn Fn() + Send + Sync + 'static> {
|
||||||
|
let (chan, id) = (self.tasks.sender.clone(), self.id);
|
||||||
|
Arc::new(move || drop(chan.unbounded_send(SchedulerMsg::Immediate(id))))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Schedule an update for any component given its [`ScopeId`].
|
||||||
|
///
|
||||||
|
/// A component's [`ScopeId`] can be obtained from `use_hook` or the [`ScopeState::scope_id`] method.
|
||||||
|
///
|
||||||
|
/// This method should be used when you want to schedule an update for a component
|
||||||
|
pub fn schedule_update_any(&self) -> Arc<dyn Fn(ScopeId) + Send + Sync> {
|
||||||
|
let chan = self.tasks.sender.clone();
|
||||||
|
Arc::new(move |id| {
|
||||||
|
chan.unbounded_send(SchedulerMsg::Immediate(id)).unwrap();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Return any context of type T if it exists on this scope
|
/// Return any context of type T if it exists on this scope
|
||||||
pub fn has_context<T: 'static + Clone>(&self) -> Option<T> {
|
pub fn has_context<T: 'static + Clone>(&self) -> Option<T> {
|
||||||
self.shared_contexts
|
self.shared_contexts
|
||||||
@@ -355,4 +376,11 @@ impl ScopeId {
|
|||||||
pub fn needs_update(self) {
|
pub fn needs_update(self) {
|
||||||
with_scope(self, |cx| cx.needs_update());
|
with_scope(self, |cx| cx.needs_update());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a subscription that schedules a future render for the reference component. Unlike [`Self::needs_update`], this function will work outside of the dioxus runtime.
|
||||||
|
///
|
||||||
|
/// ## Notice: you should prefer using [`dioxus_core::schedule_update_any`] and [`Self::scope_id`]
|
||||||
|
pub fn schedule_update(&self) -> Arc<dyn Fn() + Send + Sync + 'static> {
|
||||||
|
with_scope(*self, |cx| cx.schedule_update()).expect("to be in a dioxus runtime")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -549,7 +549,9 @@ impl VirtualDom {
|
|||||||
pub fn rebuild(&mut self, to: &mut impl WriteMutations) {
|
pub fn rebuild(&mut self, to: &mut impl WriteMutations) {
|
||||||
self.flush_templates(to);
|
self.flush_templates(to);
|
||||||
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
let _runtime = RuntimeGuard::new(self.runtime.clone());
|
||||||
match self.run_scope(ScopeId::ROOT) {
|
let new_nodes = self.run_scope(ScopeId::ROOT);
|
||||||
|
self.scopes[ScopeId::ROOT.0].last_rendered_node = Some(new_nodes.clone());
|
||||||
|
match new_nodes {
|
||||||
// Rebuilding implies we append the created elements to the root
|
// Rebuilding implies we append the created elements to the root
|
||||||
RenderReturn::Ready(node) => {
|
RenderReturn::Ready(node) => {
|
||||||
let m = self.create_scope(ScopeId::ROOT, &node, to);
|
let m = self.create_scope(ScopeId::ROOT, &node, to);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use dioxus_core::prelude::consume_context;
|
use dioxus_core::prelude::consume_context;
|
||||||
use dioxus_core::prelude::provide_context;
|
use dioxus_core::prelude::provide_context;
|
||||||
|
use dioxus_core::ScopeId;
|
||||||
use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator};
|
use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator};
|
||||||
use std::{cell::RefCell, rc::Rc};
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
@@ -9,13 +10,13 @@ use crate::{query::Query, DesktopContext};
|
|||||||
|
|
||||||
/// Provides the DesktopEvalProvider through [`cx.provide_context`].
|
/// Provides the DesktopEvalProvider through [`cx.provide_context`].
|
||||||
pub fn init_eval() {
|
pub fn init_eval() {
|
||||||
let desktop_ctx = consume_context::<DesktopContext>().unwrap();
|
let desktop_ctx = ScopeId::ROOT.consume_context::<DesktopContext>().unwrap();
|
||||||
let provider: Rc<dyn EvalProvider> = Rc::new(DesktopEvalProvider { desktop_ctx });
|
let provider: Rc<dyn EvalProvider> = Rc::new(DesktopEvalProvider { desktop_ctx });
|
||||||
provide_context(provider);
|
ScopeId::ROOT.provide_context(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reprents the desktop-target's provider of evaluators.
|
/// Represents the desktop-target's provider of evaluators.
|
||||||
pub struct DesktopEvalProvider {
|
pub(crate) struct DesktopEvalProvider {
|
||||||
desktop_ctx: DesktopContext,
|
desktop_ctx: DesktopContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,8 +26,8 @@ impl EvalProvider for DesktopEvalProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reprents a desktop-target's JavaScript evaluator.
|
/// Represents a desktop-target's JavaScript evaluator.
|
||||||
pub struct DesktopEvaluator {
|
pub(crate) struct DesktopEvaluator {
|
||||||
query: Rc<RefCell<Query<serde_json::Value>>>,
|
query: Rc<RefCell<Query<serde_json::Value>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-27
@@ -55,42 +55,42 @@ macro_rules! to_owned {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod computed;
|
// pub mod computed;
|
||||||
|
|
||||||
mod use_on_destroy;
|
// mod use_on_destroy;
|
||||||
pub use use_on_destroy::*;
|
// pub use use_on_destroy::*;
|
||||||
|
|
||||||
mod use_const;
|
// mod use_const;
|
||||||
pub use use_const::*;
|
// pub use use_const::*;
|
||||||
|
|
||||||
mod use_context;
|
// mod use_context;
|
||||||
pub use use_context::*;
|
// pub use use_context::*;
|
||||||
|
|
||||||
mod use_state;
|
// mod use_state;
|
||||||
pub use use_state::{use_state, UseState};
|
// pub use use_state::{use_state, UseState};
|
||||||
|
|
||||||
mod use_ref;
|
// mod use_ref;
|
||||||
pub use use_ref::*;
|
// pub use use_ref::*;
|
||||||
|
|
||||||
mod use_shared_state;
|
// mod use_shared_state;
|
||||||
pub use use_shared_state::*;
|
// pub use use_shared_state::*;
|
||||||
|
|
||||||
mod use_coroutine;
|
// mod use_coroutine;
|
||||||
pub use use_coroutine::*;
|
// pub use use_coroutine::*;
|
||||||
|
|
||||||
mod use_future;
|
// mod use_future;
|
||||||
pub use use_future::*;
|
// pub use use_future::*;
|
||||||
|
|
||||||
mod use_effect;
|
// mod use_effect;
|
||||||
pub use use_effect::*;
|
// pub use use_effect::*;
|
||||||
|
|
||||||
mod use_callback;
|
// mod use_callback;
|
||||||
pub use use_callback::*;
|
// pub use use_callback::*;
|
||||||
|
|
||||||
mod use_memo;
|
// mod use_memo;
|
||||||
pub use use_memo::*;
|
// pub use use_memo::*;
|
||||||
|
|
||||||
mod use_on_create;
|
// mod use_on_create;
|
||||||
pub use use_on_create::*;
|
// pub use use_on_create::*;
|
||||||
mod use_root_context;
|
// mod use_root_context;
|
||||||
pub use use_root_context::*;
|
// pub use use_root_context::*;
|
||||||
@@ -68,7 +68,7 @@ impl ToTokens for ElementAttrNamed {
|
|||||||
let value = &self.attr.value;
|
let value = &self.attr.value;
|
||||||
let value = quote! { #value };
|
let value = quote! { #value };
|
||||||
quote! {
|
quote! {
|
||||||
__cx.attr(
|
::dioxus::core::Attribute::new(
|
||||||
#attribute,
|
#attribute,
|
||||||
#value,
|
#value,
|
||||||
#ns,
|
#ns,
|
||||||
@@ -79,7 +79,7 @@ impl ToTokens for ElementAttrNamed {
|
|||||||
ElementAttrValue::EventTokens(tokens) => match &self.attr.name {
|
ElementAttrValue::EventTokens(tokens) => match &self.attr.name {
|
||||||
ElementAttrName::BuiltIn(name) => {
|
ElementAttrName::BuiltIn(name) => {
|
||||||
quote! {
|
quote! {
|
||||||
dioxus_elements::events::#name(__cx, #tokens)
|
dioxus_elements::events::#name(#tokens)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ElementAttrName::Custom(_) => todo!(),
|
ElementAttrName::Custom(_) => todo!(),
|
||||||
|
|||||||
@@ -189,11 +189,11 @@ impl ToTokens for Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
__cx.component(
|
::dioxus::core::DynamicNode::Component(::dioxus::core::VComponent::new(
|
||||||
#gen_name,
|
#gen_name,
|
||||||
#builder,
|
#builder,
|
||||||
#fn_name
|
#fn_name
|
||||||
)
|
))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,10 +217,10 @@ impl ToTokens for ContentField {
|
|||||||
match self {
|
match self {
|
||||||
ContentField::ManExpr(e) => e.to_tokens(tokens),
|
ContentField::ManExpr(e) => e.to_tokens(tokens),
|
||||||
ContentField::Formatted(s) => tokens.append_all(quote! {
|
ContentField::Formatted(s) => tokens.append_all(quote! {
|
||||||
__cx.raw_text(#s)
|
#s.to_string()
|
||||||
}),
|
}),
|
||||||
ContentField::OnHandlerRaw(e) => tokens.append_all(quote! {
|
ContentField::OnHandlerRaw(e) => tokens.append_all(quote! {
|
||||||
__cx.event_handler(#e)
|
::dioxus::core::Attribute::EventHandler(EventHandler::new(#e))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,11 +184,11 @@ impl ToTokens for Element {
|
|||||||
.filter(|f| !matches!(f.attr.value, ElementAttrValue::EventTokens { .. }));
|
.filter(|f| !matches!(f.attr.value, ElementAttrValue::EventTokens { .. }));
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
__cx.element(
|
::dioxus::core::Element::new(
|
||||||
#name,
|
#name,
|
||||||
__cx.bump().alloc([ #(#listeners),* ]),
|
vec![ #(#listeners),* ],
|
||||||
__cx.bump().alloc([ #(#attr),* ]),
|
vec![ #(#attr),* ],
|
||||||
__cx.bump().alloc([ #(#children),* ]),
|
vec![ #(#children),* ],
|
||||||
#key,
|
#key,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl CallBody {
|
|||||||
&self,
|
&self,
|
||||||
template: Option<CallBody>,
|
template: Option<CallBody>,
|
||||||
location: &'static str,
|
location: &'static str,
|
||||||
) -> Option<Template<'static>> {
|
) -> Option<Template> {
|
||||||
let mut renderer: TemplateRenderer = TemplateRenderer {
|
let mut renderer: TemplateRenderer = TemplateRenderer {
|
||||||
roots: &self.roots,
|
roots: &self.roots,
|
||||||
location: None,
|
location: None,
|
||||||
@@ -138,7 +138,6 @@ impl ToTokens for RenderCallBody {
|
|||||||
|
|
||||||
out_tokens.append_all(quote! {
|
out_tokens.append_all(quote! {
|
||||||
Some({
|
Some({
|
||||||
let __cx = cx;
|
|
||||||
#body
|
#body
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -156,7 +155,7 @@ impl<'a> TemplateRenderer<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
previous_call: Option<CallBody>,
|
previous_call: Option<CallBody>,
|
||||||
location: &'static str,
|
location: &'static str,
|
||||||
) -> Option<Template<'static>> {
|
) -> Option<Template> {
|
||||||
let mut mapping = previous_call.map(|call| DynamicMapping::from(call.roots));
|
let mut mapping = previous_call.map(|call| DynamicMapping::from(call.roots));
|
||||||
|
|
||||||
let mut context = DynamicContext::default();
|
let mut context = DynamicContext::default();
|
||||||
@@ -202,7 +201,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let key_tokens = match key {
|
let key_tokens = match key {
|
||||||
Some(tok) => quote! { Some( __cx.raw_text(#tok) ) },
|
Some(tok) => quote! { Some( #tok.to_string() ) },
|
||||||
None => quote! { None },
|
None => quote! { None },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -257,9 +256,9 @@ impl<'a> ToTokens for TemplateRenderer<'a> {
|
|||||||
::dioxus::core::VNode::new(
|
::dioxus::core::VNode::new(
|
||||||
#key_tokens,
|
#key_tokens,
|
||||||
TEMPLATE,
|
TEMPLATE,
|
||||||
dioxus::core::exports::bumpalo::collections::Vec::with_capacity_in(#root_count, __cx.bump()),
|
Vec::with_capacity(#root_count),
|
||||||
__cx.bump().alloc([ #( #node_printer ),* ]),
|
vec![ #( #node_printer ),* ],
|
||||||
__cx.bump().alloc([ #( #dyn_attr_printer ),* ]),
|
vec![ #( #dyn_attr_printer ),* ],
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -360,7 +359,7 @@ impl<'a> DynamicContext<'a> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
root: &'a BodyNode,
|
root: &'a BodyNode,
|
||||||
mapping: &mut Option<DynamicMapping>,
|
mapping: &mut Option<DynamicMapping>,
|
||||||
) -> Option<TemplateNode<'static>> {
|
) -> Option<TemplateNode> {
|
||||||
match root {
|
match root {
|
||||||
BodyNode::Element(el) => {
|
BodyNode::Element(el) => {
|
||||||
let element_name_rust = el.name.to_string();
|
let element_name_rust = el.name.to_string();
|
||||||
|
|||||||
@@ -122,11 +122,11 @@ impl ToTokens for BodyNode {
|
|||||||
BodyNode::Element(el) => el.to_tokens(tokens),
|
BodyNode::Element(el) => el.to_tokens(tokens),
|
||||||
BodyNode::Component(comp) => comp.to_tokens(tokens),
|
BodyNode::Component(comp) => comp.to_tokens(tokens),
|
||||||
BodyNode::Text(txt) => tokens.append_all(quote! {
|
BodyNode::Text(txt) => tokens.append_all(quote! {
|
||||||
__cx.text_node(#txt)
|
::dioxus::core::DynamicNode::Text(::dioxus::core::VText::new(#txt.to_string()))
|
||||||
}),
|
}),
|
||||||
BodyNode::RawExpr(exp) => tokens.append_all(quote! {
|
BodyNode::RawExpr(exp) => tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
let ___nodes = (#exp).into_dyn_node(__cx);
|
let ___nodes = (#exp).into_dyn_node();
|
||||||
___nodes
|
___nodes
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -145,7 +145,7 @@ impl ToTokens for BodyNode {
|
|||||||
// And then we can return them into the dyn loop
|
// And then we can return them into the dyn loop
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
let ___nodes =(#expr).into_iter().map(|#pat| { #renderer }).into_dyn_node(__cx);
|
let ___nodes = (#expr).into_iter().map(|#pat| { #renderer }).into_dyn_node();
|
||||||
___nodes
|
___nodes
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -154,7 +154,7 @@ impl ToTokens for BodyNode {
|
|||||||
if is_if_chain_terminated(chain) {
|
if is_if_chain_terminated(chain) {
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
let ___nodes = (#chain).into_dyn_node(__cx);
|
let ___nodes = (#chain).into_dyn_node();
|
||||||
___nodes
|
___nodes
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -211,7 +211,7 @@ impl ToTokens for BodyNode {
|
|||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
let ___nodes = (#body).into_dyn_node(__cx);
|
let ___nodes = (#body).into_dyn_node();
|
||||||
___nodes
|
___nodes
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -38,21 +38,20 @@ pub(crate) fn get_effect_stack() -> EffectStack {
|
|||||||
|
|
||||||
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
|
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
|
||||||
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
||||||
pub fn use_effect(cx: &ScopeState, callback: impl FnMut() + 'static) {
|
pub fn use_effect(callback: impl FnMut() + 'static) {
|
||||||
cx.use_hook(|| Effect::new(callback));
|
once(|| Effect::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
|
/// Create a new effect. The effect will be run immediately and whenever any signal it reads changes.
|
||||||
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
/// The signal will be owned by the current component and will be dropped when the component is dropped.
|
||||||
pub fn use_effect_with_dependencies<D: Dependency>(
|
pub fn use_effect_with_dependencies<D: Dependency>(
|
||||||
cx: &ScopeState,
|
|
||||||
dependencies: D,
|
dependencies: D,
|
||||||
mut callback: impl FnMut(D::Out) + 'static,
|
mut callback: impl FnMut(D::Out) + 'static,
|
||||||
) where
|
) where
|
||||||
D::Out: 'static,
|
D::Out: 'static,
|
||||||
{
|
{
|
||||||
let dependencies_signal = use_signal(cx, || dependencies.out());
|
let dependencies_signal = use_signal(|| dependencies.out());
|
||||||
cx.use_hook(|| {
|
once(|| {
|
||||||
Effect::new(move || {
|
Effect::new(move || {
|
||||||
let deref = &*dependencies_signal.read();
|
let deref = &*dependencies_signal.read();
|
||||||
callback(deref.clone());
|
callback(deref.clone());
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ fn owner_in_scope(scope: ScopeId) -> Rc<Owner> {
|
|||||||
Some(rt) => rt,
|
Some(rt) => rt,
|
||||||
None => {
|
None => {
|
||||||
let owner = Rc::new(current_store().owner());
|
let owner = Rc::new(current_store().owner());
|
||||||
provide_context_to_scope(scope, owner).expect("in a virtual dom")
|
scope.provide_context(owner).expect("in a virtual dom")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,8 @@ use crate::{get_effect_stack, signal::SignalData, CopyValue, Effect, ReadOnlySig
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
||||||
pub fn use_selector<R: PartialEq>(
|
pub fn use_selector<R: PartialEq>(f: impl FnMut() -> R + 'static) -> ReadOnlySignal<R> {
|
||||||
cx: &ScopeState,
|
once(|| selector(f))
|
||||||
f: impl FnMut() -> R + 'static,
|
|
||||||
) -> ReadOnlySignal<R> {
|
|
||||||
*cx.use_hook(|| selector(f))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new Selector with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
|
/// Creates a new Selector with some local dependencies. The selector will be run immediately and whenever any signal it reads or any dependencies it tracks changes
|
||||||
@@ -47,15 +44,14 @@ pub fn use_selector<R: PartialEq>(
|
|||||||
/// ```
|
/// ```
|
||||||
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
#[must_use = "Consider using `use_effect` to rerun a callback when dependencies change"]
|
||||||
pub fn use_selector_with_dependencies<R: PartialEq, D: Dependency>(
|
pub fn use_selector_with_dependencies<R: PartialEq, D: Dependency>(
|
||||||
cx: &ScopeState,
|
|
||||||
dependencies: D,
|
dependencies: D,
|
||||||
mut f: impl FnMut(D::Out) -> R + 'static,
|
mut f: impl FnMut(D::Out) -> R + 'static,
|
||||||
) -> ReadOnlySignal<R>
|
) -> ReadOnlySignal<R>
|
||||||
where
|
where
|
||||||
D::Out: 'static,
|
D::Out: 'static,
|
||||||
{
|
{
|
||||||
let dependencies_signal = use_signal(cx, || dependencies.out());
|
let dependencies_signal = use_signal(|| dependencies.out());
|
||||||
let selector = *cx.use_hook(|| {
|
let selector = once(|| {
|
||||||
selector(move || {
|
selector(move || {
|
||||||
let deref = &*dependencies_signal.read();
|
let deref = &*dependencies_signal.read();
|
||||||
f(deref.clone())
|
f(deref.clone())
|
||||||
@@ -87,9 +83,9 @@ pub fn selector<R: PartialEq>(mut f: impl FnMut() -> R + 'static) -> ReadOnlySig
|
|||||||
state.inner.value.set(SignalData {
|
state.inner.value.set(SignalData {
|
||||||
subscribers: Default::default(),
|
subscribers: Default::default(),
|
||||||
effect_subscribers: Default::default(),
|
effect_subscribers: Default::default(),
|
||||||
update_any: schedule_update_any().expect("in a virtual dom"),
|
|
||||||
value: f(),
|
value: f(),
|
||||||
effect_stack: get_effect_stack(),
|
effect_stack: get_effect_stack(),
|
||||||
|
update_any: schedule_update_any(),
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
get_effect_stack().effects.write().pop();
|
get_effect_stack().effects.write().pop();
|
||||||
|
|||||||
@@ -7,8 +7,9 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use dioxus_core::{
|
use dioxus_core::{
|
||||||
|
once,
|
||||||
prelude::{current_scope_id, has_context, provide_context, schedule_update_any},
|
prelude::{current_scope_id, has_context, provide_context, schedule_update_any},
|
||||||
ScopeId, ScopeState,
|
ScopeId,
|
||||||
};
|
};
|
||||||
use generational_box::{GenerationalRef, GenerationalRefMut};
|
use generational_box::{GenerationalRef, GenerationalRefMut};
|
||||||
|
|
||||||
@@ -47,11 +48,11 @@ use crate::{get_effect_stack, CopyValue, Effect, EffectStack};
|
|||||||
/// ```
|
/// ```
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn use_signal<T: 'static>(cx: &ScopeState, f: impl FnOnce() -> T) -> Signal<T> {
|
pub fn use_signal<T: 'static>(f: impl FnOnce() -> T) -> Signal<T> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let caller = std::panic::Location::caller();
|
let caller = std::panic::Location::caller();
|
||||||
|
|
||||||
*cx.use_hook(|| {
|
once(|| {
|
||||||
Signal::new_with_caller(
|
Signal::new_with_caller(
|
||||||
f(),
|
f(),
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -155,7 +156,7 @@ impl<T: 'static> Signal<T> {
|
|||||||
inner: CopyValue::new(SignalData {
|
inner: CopyValue::new(SignalData {
|
||||||
subscribers: Default::default(),
|
subscribers: Default::default(),
|
||||||
effect_subscribers: Default::default(),
|
effect_subscribers: Default::default(),
|
||||||
update_any: schedule_update_any().expect("in a virtual dom"),
|
update_any: schedule_update_any(),
|
||||||
value,
|
value,
|
||||||
effect_stack: get_effect_stack(),
|
effect_stack: get_effect_stack(),
|
||||||
}),
|
}),
|
||||||
@@ -172,7 +173,7 @@ impl<T: 'static> Signal<T> {
|
|||||||
SignalData {
|
SignalData {
|
||||||
subscribers: Default::default(),
|
subscribers: Default::default(),
|
||||||
effect_subscribers: Default::default(),
|
effect_subscribers: Default::default(),
|
||||||
update_any: schedule_update_any().expect("in a virtual dom"),
|
update_any: schedule_update_any(),
|
||||||
value,
|
value,
|
||||||
effect_stack: get_effect_stack(),
|
effect_stack: get_effect_stack(),
|
||||||
},
|
},
|
||||||
@@ -189,7 +190,7 @@ impl<T: 'static> Signal<T> {
|
|||||||
SignalData {
|
SignalData {
|
||||||
subscribers: Default::default(),
|
subscribers: Default::default(),
|
||||||
effect_subscribers: Default::default(),
|
effect_subscribers: Default::default(),
|
||||||
update_any: schedule_update_any().expect("in a virtual dom"),
|
update_any: schedule_update_any(),
|
||||||
value,
|
value,
|
||||||
effect_stack: get_effect_stack(),
|
effect_stack: get_effect_stack(),
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in new issue
Block a user