ソースを参照

Feat: more cleanup

Jonathan Kelley 4 年 前
コミット
5a9155b

+ 2 - 0
packages/cli/src/builder.rs

@@ -62,6 +62,8 @@ pub fn build(config: &Config, _build_config: &BuildConfig) -> Result<()> {
     let mut child = cmd.spawn()?;
     let _err_code = child.wait()?;
 
+    info!("Build complete!");
+
     // [2] Establish the output directory structure
     let bindgen_outdir = out_dir.join("wasm");
 

+ 8 - 1
packages/cli/src/cli.rs

@@ -1,4 +1,3 @@
-
 use argh::FromArgs;
 
 #[derive(FromArgs, PartialEq, Debug)]
@@ -43,6 +42,10 @@ pub struct BuildOptions {
     /// an example in the crate
     #[argh(option)]
     pub example: Option<String>,
+
+    /// develop in release mode
+    #[argh(switch, short = 'r')]
+    pub release: bool,
 }
 
 /// 🛠 Start a development server
@@ -52,4 +55,8 @@ pub struct DevelopOptions {
     /// an example in the crate
     #[argh(option)]
     pub example: Option<String>,
+
+    /// develop in release mode
+    #[argh(switch, short = 'r')]
+    pub release: bool,
 }

+ 8 - 3
packages/cli/src/config.rs

@@ -2,7 +2,6 @@ use crate::{
     cli::{BuildOptions, DevelopOptions},
     error::Result,
 };
-// use log::{info, warn};
 use std::{io::Write, path::PathBuf, process::Command};
 
 #[derive(Debug, Clone)]
@@ -70,10 +69,16 @@ impl Config {
         self
     }
 
+    pub fn with_release(&mut self, release: bool) -> &mut Self {
+        self.release = release;
+        self
+    }
+
     pub fn with_build_options(&mut self, options: &BuildOptions) {
         if let Some(name) = &options.example {
             self.as_example(name.clone());
         }
+        self.release = options.release;
         self.out_dir = options.outdir.clone().into();
     }
 
@@ -81,7 +86,7 @@ impl Config {
         if let Some(name) = &options.example {
             self.as_example(name.clone());
         }
-        let outdir = tempfile::Builder::new().tempdir().expect("").into_path();
-        self.out_dir = outdir;
+        self.release = options.release;
+        self.out_dir = tempfile::Builder::new().tempdir().expect("").into_path();
     }
 }

+ 1 - 1
packages/cli/src/develop.rs

@@ -57,7 +57,7 @@ async fn watch_directory(config: Config) -> Result<()> {
         .watch(src_dir.join("examples"), RecursiveMode::Recursive)
         .expect("Failed to watch dir");
 
-    let build_config = BuildConfig::default();
+    let mut build_config = BuildConfig::default();
 
     'run: loop {
         crate::builder::build(&config, &build_config)?;

+ 10 - 24
packages/core-macro/src/lib.rs

@@ -1,41 +1,30 @@
 use proc_macro::TokenStream;
-use quote::{quote, quote_spanned, ToTokens};
-use syn::spanned::Spanned;
-use syn::{
-    parse::{Parse, ParseStream},
-    Signature,
-};
-use syn::{
-    parse_macro_input, Attribute, Block, FnArg, Ident, Item, ItemFn, ReturnType, Type, Visibility,
-};
+use quote::ToTokens;
+use syn::parse_macro_input;
 
 mod fc;
 mod htm;
 mod ifmt;
 mod rsxt;
-// mod styles;
 
 /// The html! macro makes it easy for developers to write jsx-style markup in their components.
 /// We aim to keep functional parity with html templates.
 #[proc_macro]
 pub fn html(s: TokenStream) -> TokenStream {
-    let html: htm::HtmlRender = match syn::parse(s) {
-        Ok(s) => s,
-        Err(e) => return e.to_compile_error().into(),
-    };
-    html.to_token_stream().into()
+    match syn::parse::<htm::HtmlRender>(s) {
+        Err(e) => e.to_compile_error().into(),
+        Ok(s) => s.to_token_stream().into(),
+    }
 }
 
 /// The html! macro makes it easy for developers to write jsx-style markup in their components.
 /// We aim to keep functional parity with html templates.
 #[proc_macro]
 pub fn rsx(s: TokenStream) -> TokenStream {
-    let template: rsxt::RsxRender = match syn::parse(s) {
-        Ok(s) => s,
-        Err(e) => return e.to_compile_error().into(),
-    };
-
-    template.to_token_stream().into()
+    match syn::parse::<rsxt::RsxRender>(s) {
+        Err(e) => e.to_compile_error().into(),
+        Ok(s) => s.to_token_stream().into(),
+    }
 }
 
 /// Label a function or static closure as a functional component.
@@ -49,9 +38,6 @@ pub fn fc(attr: TokenStream, item: TokenStream) -> TokenStream {
     function_component_impl(item)
         .unwrap_or_else(|err| err.to_compile_error())
         .into()
-
-    // function_component_impl(attr, item)
-    // let attr = parse_macro_input!(attr as FunctionComponentName);
 }
 
 #[proc_macro]

+ 2 - 2
packages/core-macro/src/rsxt.rs

@@ -144,9 +144,9 @@ impl ToTokens for ToToksCtx<&Element> {
     fn to_tokens(&self, tokens: &mut TokenStream2) {
         // todo!()
         // // let ctx = self.ctx;
-        let name = &self.inner.name;
+        let name = &self.inner.name.to_string();
         tokens.append_all(quote! {
-            dioxus::builder::ElementBuilder::new(ctx, "#name")
+            dioxus::builder::ElementBuilder::new(ctx, #name)
         });
         for attr in self.inner.attrs.iter() {
             self.recurse(attr).to_tokens(tokens);

+ 13 - 15
packages/core/src/context.rs

@@ -2,7 +2,6 @@ use crate::nodes::VNode;
 use crate::prelude::*;
 use bumpalo::Bump;
 use hooks::Hook;
-use log::info;
 use std::{
     any::TypeId, borrow::Borrow, cell::RefCell, future::Future, marker::PhantomData, ops::Deref,
     rc::Rc, sync::atomic::AtomicUsize,
@@ -56,6 +55,8 @@ impl<'a> Context<'a> {
         todo!("Children API not yet implemented for component Context")
     }
 
+    pub fn callback(&self, _f: impl Fn(()) + 'a) {}
+
     /// Create a subscription that schedules a future render for the reference component
     pub fn schedule_update(&self) -> impl Fn() -> () {
         // log::debug!()
@@ -63,6 +64,16 @@ impl<'a> Context<'a> {
         || {}
     }
 
+    /// Create a suspended component from a future.
+    ///
+    /// When the future completes, the component will be renderered
+    pub fn suspend(
+        &self,
+        _fut: impl Future<Output = impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a>>,
+    ) -> VNode<'a> {
+        todo!()
+    }
+
     /// Take a lazy VNode structure and actually build it with the context of the VDom's efficient VNode allocator.
     ///
     /// This function consumes the context and absorb the lifetime, so these VNodes *must* be returned.
@@ -84,25 +95,12 @@ impl<'a> Context<'a> {
             idx: 0.into(),
             scope: self.scope,
         };
-        // todo!();
-        let safe_nodes = lazy_nodes(&ctx);
 
+        let safe_nodes = lazy_nodes(&ctx);
         let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
         self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
         DomTree {}
     }
-
-    pub fn callback(&self, _f: impl Fn(()) + 'a) {}
-
-    /// Create a suspended component from a future.
-    ///
-    /// When the future completes, the component will be renderered
-    pub fn suspend(
-        &self,
-        _fut: impl Future<Output = impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a>>,
-    ) -> VNode<'a> {
-        todo!()
-    }
 }
 
 // NodeCtx is used to build VNodes in the component's memory space.

+ 9 - 26
packages/core/src/diff.rs

@@ -58,13 +58,11 @@ pub struct DiffMachine<'a> {
 
 impl<'a> DiffMachine<'a> {
     pub fn new(bump: &'a Bump) -> Self {
-        // log::debug!("starting diff machine");
         Self {
             change_list: EditMachine::new(bump),
             immediate_queue: Vec::new(),
             diffed: FxHashSet::default(),
             need_to_diff: FxHashSet::default(),
-            // current_idx: None,
         }
     }
 
@@ -72,19 +70,13 @@ impl<'a> DiffMachine<'a> {
         self.change_list.emitter
     }
 
-    pub fn diff_node(
-        &mut self,
-        old: &VNode<'a>,
-        new: &VNode<'a>,
-        // scope: Option<generational_arena::Index>,
-    ) {
+    pub fn diff_node(&mut self, old: &VNode<'a>, new: &VNode<'a>) {
         /*
         For each valid case, we "commit traversal", meaning we save this current position in the tree.
         Then, we diff and queue an edit event (via chagelist). s single trees - when components show up, we save that traversal and then re-enter later.
         When re-entering, we reuse the EditList in DiffState
         */
         match (old, new) {
-            // This case occurs when two text nodes are generation
             (VNode::Text(VText { text: old_text }), VNode::Text(VText { text: new_text })) => {
                 if old_text != new_text {
                     self.change_list.commit_traversal();
@@ -93,12 +85,8 @@ impl<'a> DiffMachine<'a> {
             }
 
             (VNode::Text(_), VNode::Element(_)) => {
-                // TODO: Hook up the events properly
-                // todo!("Hook up events registry");
                 self.change_list.commit_traversal();
-                // diff_support::create(cached_set, self.change_list, registry, new, cached_roots);
                 self.create(new);
-                // registry.remove_subtree(&old);
                 self.change_list.replace_with();
             }
 
@@ -121,30 +109,25 @@ impl<'a> DiffMachine<'a> {
                 self.diff_children(eold.children, enew.children);
             }
 
-            (VNode::Component(_), VNode::Component(_)) => {
-                todo!("Usage of component VNode not currently supported");
-            }
+            (VNode::Component(cold), VNode::Component(cnew)) => {
+                if cold.comp != cnew.comp {
+                    // queue an event to mount this new component
+                    return;
+                }
+
+                // compare props.... somehow.....
 
-            (_, VNode::Component(_)) => {
                 todo!("Usage of component VNode not currently supported");
             }
 
-            (VNode::Component(_), _) => {
+            (_, VNode::Component(_)) | (VNode::Component(_), _) => {
                 todo!("Usage of component VNode not currently supported");
             }
 
             (VNode::Suspended, _) | (_, VNode::Suspended) => {
-                // (VNode::Element(_), VNode::Suspended) => {}
-                // (VNode::Text(_), VNode::Suspended) => {}
-                // (VNode::Component(_), VNode::Suspended) => {}
-                // (VNode::Suspended, VNode::Element(_)) => {}
-                // (VNode::Suspended, VNode::Text(_)) => {}
-                // (VNode::Suspended, VNode::Suspended) => {}
-                // (VNode::Suspended, VNode::Component(_)) => {}
                 todo!("Suspended components not currently available")
             }
         }
-        // self.current_idx = None;
     }
 
     // Diff event listeners between `old` and `new`.

+ 0 - 32
packages/core/src/error.rs

@@ -1,5 +1,4 @@
 use thiserror::Error as ThisError;
-
 pub type Result<T, E = Error> = std::result::Result<T, E>;
 
 #[derive(ThisError, Debug)]
@@ -13,37 +12,6 @@ pub enum Error {
     #[error("Base scope has not been mounted yet")]
     NotMounted,
 
-    // #[error("Out of compute credits")]
-    // OutOfCredits,
-
-    // /// Used when errors need to propogate but are too unique to be typed
-    // #[error("{0}")]
-    // Unique(String),
-
-    // #[error("GraphQL error: {0}")]
-    // GraphQL(String),
-
-    // // TODO(haze): Remove, or make a better error. This is pretty much useless
-    // #[error("GraphQL response mismatch. Got {found} but expected {expected}")]
-    // GraphQLMisMatch {
-    //     expected: &'static str,
-    //     found: String,
-    // },
-
-    // #[error("Difference detected in SystemTime! {0}")]
-    // SystemTime(#[from] std::time::SystemTimeError),
-
-    // #[error("Failed to parse Integer")]
-    // ParseInt(#[from] std::num::ParseIntError),
-
-    // #[error("")]
-    // MissingAuthentication,
-
-    // #[error("Failed to create experiment run: {0}")]
-    // FailedToCreateExperimentRun(String),
-
-    // #[error("Could not find shared behavior with ID {0}")]
-    // MissingSharedBehavior(String),
     #[error("I/O Error: {0}")]
     IO(#[from] std::io::Error),
 }

+ 2 - 2
packages/core/src/hooks.rs

@@ -28,8 +28,8 @@ mod use_state_def {
     /// ```ignore
     /// static Example: FC<()> = |ctx| {
     ///     let (counter, set_counter) = use_state(ctx, || 0);
-    ///     let increment = || set_couter(counter + 1);
-    ///     let decrement = || set_couter(counter + 1);
+    ///     let increment = |_| set_couter(counter + 1);
+    ///     let decrement = |_| set_couter(counter + 1);
     ///
     ///     html! {
     ///         <div>

+ 2 - 0
packages/core/src/nodebuilder.rs

@@ -442,6 +442,8 @@ where
         self.children.push(child);
         self
     }
+
+    // pub fn virtual_child(mut self)
 }
 
 /// Construct a text VNode.

+ 44 - 8
packages/core/src/nodes.rs

@@ -296,21 +296,57 @@ mod vtext {
 /// Virtual Components for custom user-defined components
 /// Only supports the functional syntax
 mod vcomponent {
-    use crate::innerlude::FC;
-    use std::marker::PhantomData;
+    use crate::innerlude::{Context, FC};
+    use std::{any::TypeId, marker::PhantomData};
+
+    use super::DomTree;
 
     #[derive(Debug)]
     pub struct VComponent<'src> {
         _p: PhantomData<&'src ()>,
-        props: Box<dyn std::any::Any>,
-        // props: Box<dyn Properties + 'src>,
-        caller: *const (),
+        pub(crate) props: Box<dyn std::any::Any>,
+        pub(crate) props_type: TypeId,
+        pub(crate) comp: *const (),
+        pub(crate) caller: Caller,
+    }
+
+    pub struct Caller(Box<dyn Fn(Context) -> DomTree>);
+    impl std::fmt::Debug for Caller {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            todo!()
+        }
     }
 
     impl<'a> VComponent<'a> {
-        pub fn new<P>(caller: FC<P>, props: P) -> Self {
-            let _caller = caller as *const ();
-            let _props = Box::new(props);
+        // use the type parameter on props creation and move it into a portable context
+        // this lets us keep scope generic *and* downcast its props when we need to:
+        // - perform comparisons when diffing (memoization)
+        // -
+        pub fn new<P>(comp: FC<P>, props: P) -> Self {
+            let caller = move |ctx: Context| {
+                let t = comp(ctx, &props);
+                t
+            };
+            // let _caller = comp as *const ();
+            // let _props = Box::new(props);
+
+            // cast to static?
+            // how do we save the type of props ?
+            // do it in the caller function?
+            // something like
+
+            // the "true" entrpypoint
+            //
+            // |caller| caller.call(fn, Props {})
+            // fn call<P>(f, new_props) {
+            //     let old_props = old.downcast_ref::<P>();
+            //     if new_props == old_props {
+            //         return;
+            //     } else {
+            //         // set the new props
+            //         // call the fn
+            //     }
+            // }
 
             todo!()
             // Self {

+ 6 - 30
packages/core/src/patch.rs

@@ -107,7 +107,6 @@ pub enum Edit<'d> {
     RemoveListener {
         event: &'d str,
     },
-    // NewListener { event: &'d str, id: usize, s: ScopeIdx },
 }
 
 pub type EditList<'src> = Vec<Edit<'src>>;
@@ -167,40 +166,17 @@ impl<'b> EditMachine<'b> {
 
     pub fn commit_traversal(&mut self) {
         if self.traversal.is_committed() {
-            log::debug!("Traversal already committed");
             return;
         }
 
         for mv in self.traversal.commit() {
             match mv {
-                MoveTo::Parent => {
-                    log::debug!("emit: pop");
-                    self.emitter.push(Edit::Pop {});
-                    // self.emitter.pop();
-                }
-                MoveTo::Child(n) => {
-                    log::debug!("emit: push_child({})", n);
-                    self.emitter.push(Edit::PushChild { n });
-                }
-                MoveTo::ReverseChild(n) => {
-                    log::debug!("emit: push_reverse_child({})", n);
-                    self.emitter.push(Edit::PushReverseChild { n });
-                    // self.emitter.push_reverse_child(n);
-                }
-                MoveTo::Sibling(n) => {
-                    log::debug!("emit: pop_push_child({})", n);
-                    self.emitter.push(Edit::PopPushChild { n });
-                    // self.emitter.pop_push_child(n);
-                }
-                MoveTo::ReverseSibling(n) => {
-                    log::debug!("emit: pop_push_reverse_child({})", n);
-                    self.emitter.push(Edit::PopPushReverseChild { n });
-                }
-                MoveTo::TempChild(temp) => {
-                    log::debug!("emit: push_temporary({})", temp);
-                    self.emitter.push(Edit::PushTemporary { temp });
-                    // self.emitter.push_temporary(temp);
-                }
+                MoveTo::Parent => self.emitter.push(Edit::Pop {}),
+                MoveTo::Child(n) => self.emitter.push(Edit::PushChild { n }),
+                MoveTo::ReverseChild(n) => self.emitter.push(Edit::PushReverseChild { n }),
+                MoveTo::Sibling(n) => self.emitter.push(Edit::PopPushChild { n }),
+                MoveTo::ReverseSibling(n) => self.emitter.push(Edit::PopPushReverseChild { n }),
+                MoveTo::TempChild(temp) => self.emitter.push(Edit::PushTemporary { temp }),
             }
         }
     }

+ 31 - 99
packages/core/src/scope.rs

@@ -227,6 +227,8 @@ impl ActiveFrame {
             true => &self.frames[0],
             false => &self.frames[1],
         };
+
+        // Give out our self-referential item with our own borrowed lifetime
         unsafe {
             let unsafe_head = &raw_node.head_node;
             let safe_node = std::mem::transmute::<&VNode<'static>, &VNode<'b>>(unsafe_head);
@@ -240,6 +242,7 @@ impl ActiveFrame {
             false => &self.frames[1],
         };
 
+        // Give out our self-referential item with our own borrowed lifetime
         unsafe {
             let unsafe_head = &raw_node.head_node;
             let safe_node = std::mem::transmute::<&VNode<'static>, &VNode<'b>>(unsafe_head);
@@ -250,56 +253,28 @@ impl ActiveFrame {
     fn next(&mut self) -> &mut BumpFrame {
         self.idx.fetch_add(1, Ordering::Relaxed);
         let cur = self.idx.borrow().load(Ordering::Relaxed);
-        log::debug!("Next frame! {}", cur);
 
         if cur % 2 == 0 {
-            log::debug!("Chosing frame 0");
             &mut self.frames[0]
         } else {
-            log::debug!("Chosing frame 1");
             &mut self.frames[1]
         }
-        // match cur % 1 {
-        //     0 => {
-        //     }
-        //     1 => {
-        //     }
-        //     _ => unreachable!("mod cannot by non-zero"),
-        // }
     }
 }
 
 // #[cfg(test)]
 mod tests {
     use super::*;
-    use crate::prelude::bumpalo;
-    // use crate::prelude::bumpalo::collections::string::String;
-    use crate::prelude::format_args_f;
+    use crate::prelude::*;
 
     static ListenerTest: FC<()> = |ctx, props| {
-        ctx.render(move |c| {
-            //
-            builder::ElementBuilder::new(c, "div").finish()
+        ctx.render(html! {
+            <div onclick={|_| println!("Hell owlrld")}>
+                "hello"
+            </div>
         })
-        // ctx.render(html! {
-        //     <div onclick={|_| println!("Hell owlrld")}>
-        //         "hello"
-        //     </div>
-        // })
     };
 
-    #[test]
-    fn check_listeners() -> Result<()> {
-        todo!()
-        // let mut scope = Scope::new::<(), ()>(ListenerTest, (), None);
-        // scope.run::<()>();
-
-        // let nodes = scope.new_frame();
-        // dbg!(nodes);
-
-        // Ok(())
-    }
-
     #[test]
     fn test_scope() {
         let example: FC<()> = |ctx, props| {
@@ -316,7 +291,6 @@ mod tests {
         let mut nodes = generational_arena::Arena::new();
         nodes.insert_with(|f| {
             let scope = Scope::new::<(), ()>(example, props, f, parent);
-            //
         });
     }
 
@@ -324,103 +298,61 @@ mod tests {
     struct ExampleProps<'src> {
         name: &'src String,
     }
-    // impl<'src> Properties<'src> for ExampleProps<'src> {}
 
     #[derive(Debug)]
     struct EmptyProps<'src> {
         name: &'src String,
     }
-    // impl<'src> Properties<'src> for EmptyProps<'src> {}
 
     use crate::{builder::*, hooks::use_ref};
 
     fn example_fc<'a>(ctx: Context<'a>, props: &'a EmptyProps) -> DomTree {
-        // fn example_fc<'a>(ctx: Context<'a>, props: &'a EmptyProps<'a>) -> DomTree {
         let (content, _): (&'a String, _) = crate::hooks::use_state(&ctx, || "abcd".to_string());
-        // let (content, _): (&'a String, _) = crate::hooks::use_state(&ctx, || "abcd".to_string());
-        // let (text, set_val) = crate::hooks::use_state(&ctx, || "abcd".to_string());
 
         let childprops: ExampleProps<'a> = ExampleProps { name: content };
-        // let childprops: ExampleProps<'a> = ExampleProps { name: content };
-        ctx.render(move |ctx| {
-            todo!()
-            // let b = ctx.bump();
-            // div(b)
-            //     .child(text(props.name))
-            //     // .child(text(props.name))
-            //     .child(virtual_child::<ExampleProps>(b, childprops, child_example))
-            //     // .child(virtual_child::<ExampleProps<'a>>(b, childprops, CHILD))
-            //     // as for<'scope> fn(Context<'_>, &'scope ExampleProps<'scope>) -> DomTree
-            //     // |ctx, pops| todo!(),
-            //     // .child(virtual_child::<'a>(
-            //     //     b,
-            //     //     child_example,
-            //     //     ExampleProps { name: text },
-            //     // ))
-            //     .finish()
+        ctx.render(move |c| {
+            builder::ElementBuilder::new(c, "div")
+                .child(text(props.name))
+                .child(virtual_child::<ExampleProps>(
+                    c.bump,
+                    childprops,
+                    child_example,
+                ))
+                .finish()
         })
     }
 
     fn child_example<'b>(ctx: Context<'b>, props: &'b ExampleProps) -> DomTree {
         ctx.render(move |ctx| {
-            todo!()
-            // div(ctx.bump())
-            //     .child(text(props.name))
-            //     //
-            //     .finish()
+            builder::ElementBuilder::new(ctx, "div")
+                .child(text(props.name))
+                .finish()
         })
     }
 
     static CHILD: FC<ExampleProps> = |ctx, props: &'_ ExampleProps| {
-        // todo!()
         ctx.render(move |ctx| {
-            todo!()
-            // div(ctx.bump())
-            //     .child(text(props.name))
-            //     //
-            //     .finish()
+            builder::ElementBuilder::new(ctx, "div")
+                .child(text(props.name))
+                .finish()
         })
     };
+
     #[test]
     fn test_borrowed_scope() {
-        // use crate::builder::*;
-
         let example: FC<EmptyProps> = |ctx, props| {
-            // render counter
-            // let mut val = crate::hooks::use_ref(&ctx, || 0);
-            // val.modify(|f| {
-            //     *f += 1;
-            // });
-            // dbg!(val.current());
-            // only needs to be valid when ran?
-            // can only borrow from parent?
-            // props are boxed in parent's scope?
-            // passing complex structures down to child?
-            // stored value
-            // let (text, set_val) = crate::hooks::use_state(&ctx, || "abcd".to_string());
-
             ctx.render(move |b| {
-                todo!()
-                // div(b)
-                //     // .child(text(props.name))
-                //     // .child(virtual_child(b, CHILD, ExampleProps { name: val.as_str() }))
-                //     .child(virtual_child(b, CHILD, ExampleProps { name:  }))
-                //     .finish()
+                builder::ElementBuilder::new(b, "div")
+                    .child(virtual_child(
+                        b.bump,
+                        ExampleProps { name: props.name },
+                        CHILD,
+                    ))
+                    .finish()
             })
         };
 
         let source_text = "abcd123".to_string();
         let props = ExampleProps { name: &source_text };
-
-        // let parent = None;
-        // let mut scope =
-        //     Scope::new::<EmptyProps, EmptyProps>(example, EmptyProps { name: &() }, parent);
-        // scope.run::<ExampleProps>();
-        // scope.run::<ExampleProps>();
-        // scope.run::<ExampleProps>();
-        // scope.run::<ExampleProps>();
-        // scope.run::<ExampleProps>();
-        // let nodes = scope.current_root_node();
-        // dbg!(nodes);
     }
 }

+ 4 - 3
packages/core/src/virtual_dom.rs

@@ -25,11 +25,12 @@ pub struct VirtualDom {
     /// Will not be ready if the dom is fresh
     base_scope: ScopeIdx,
 
-    event_queue: Rc<RefCell<VecDeque<LifecycleEvent>>>,
+    event_queue: RefCell<VecDeque<LifecycleEvent>>,
 
     // todo: encapsulate more state into this so we can better reuse it
     diff_bump: Bump,
 
+    // Type of the original props. This is done so VirtualDom does not need to be generic.
     #[doc(hidden)]
     _root_prop_type: std::any::TypeId,
 }
@@ -51,7 +52,7 @@ impl VirtualDom {
     pub fn new_with_props<P: 'static>(root: FC<P>, root_props: P) -> Self {
         let mut components = Arena::new();
 
-        let event_queue = Rc::new(RefCell::new(VecDeque::new()));
+        let event_queue = RefCell::new(VecDeque::new());
 
         // Create a reference to the component in the arena
         // Note: we are essentially running the "Mount" lifecycle event manually while the vdom doesnt yet exist
@@ -212,7 +213,7 @@ impl VirtualDom {
 
     /// Pop the top event of the internal lifecycle event queu
     pub fn pop_event(&self) -> Option<LifecycleEvent> {
-        self.event_queue.as_ref().borrow_mut().pop_front()
+        self.event_queue.borrow_mut().pop_front()
     }
 
     /// With access to the virtual dom, schedule an update to the Root component's props.

+ 8 - 7
packages/web/examples/rsxt.rs

@@ -8,15 +8,14 @@ use dioxus_web::WebsysRenderer;
 // static IMG: ImgAsset = dioxus_asset!("");
 
 fn main() {
-    wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
-    console_error_panic_hook::set_once();
+    // wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
+    // console_error_panic_hook::set_once();
     wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example))
 }
 
 static Example: FC<()> = |ctx, props| {
     let (name, set_name) = use_state(&ctx, || "...?");
 
-    let handler = move |_| set_name("jill");
 
     ctx.render(rsx! {
         div { 
@@ -36,12 +35,14 @@ static Example: FC<()> = |ctx, props| {
             }
             button {  
                 class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
-                onfocus: {handler}
-                onmouseover: move |_| {
-                    set_name("jill");
-                }
+                onmouseover: move |_| set_name("jill")
                 "Jill!"
             }
+            button {  
+                class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
+                onmouseover: move |e| set_name("....")
+                "Reset!"
+            }
         }
     })
 };

+ 5 - 5
packages/web/src/lib.rs

@@ -76,27 +76,27 @@ impl WebsysRenderer {
         // todo: initialize the event registry properly on the root
 
         self.internal_dom.rebuild()?.iter().for_each(|edit| {
-            log::debug!("patching with  {:?}", edit);
+            // log::debug!("patching with  {:?}", edit);
             patch_machine.handle_edit(edit);
         });
-        log::debug!("patch stack size {:?}", patch_machine.stack);
+        // log::debug!("patch stack size {:?}", patch_machine.stack);
 
         // Event loop waits for the receiver to finish up
         // TODO! Connect the sender to the virtual dom's suspense system
         // Suspense is basically an external event that can force renders to specific nodes
         while let Some(event) = receiver.next().await {
-            log::debug!("patch stack size before {:#?}", patch_machine.stack);
+            // log::debug!("patch stack size before {:#?}", patch_machine.stack);
             // patch_machine.reset();
             // patch_machine.stack.push(root_node.clone());
             self.internal_dom
                 .progress_with_event(event)?
                 .iter()
                 .for_each(|edit| {
-                    log::debug!("edit stream {:?}", edit);
+                    // log::debug!("edit stream {:?}", edit);
                     patch_machine.handle_edit(edit);
                 });
 
-            log::debug!("patch stack size after {:#?}", patch_machine.stack);
+            // log::debug!("patch stack size after {:#?}", patch_machine.stack);
             patch_machine.reset();
             // our root node reference gets invalidated
             // not sure why