wip: rethinking stack machine

This commit is contained in:
Jonathan Kelley committed 2021-06-19 20:31:25 -04:00
1 parent 70cd46dbb2
commit 62ae5d3bb9
7 files changed
+229 -86

No files matched your search

+98
View File
@@ -391,3 +391,101 @@ static Component: FC = |ctx, name: &str| {
}
```
## Noderefs
How do we resolve noderefs in a world of patches? Patches _must_ be serializable, so if we do something like `Option<&RefCell<Slot>>`, then that must serialize as _something_ to indicate to a remote host that access to the node itself is desired. Our `Slot` type will need to be somewhat abstract.
If we add a new patch type called "BindRef" we could do something like:
```rust
enum Patch {
//...
BindAsRef { raw_node: &RefCell<Option<Slot>> }
}
```
```rust
let node_ref = use_node_ref(&ctx);
use_effect(&ctx, || {
}, []);
div { ref: node_ref,
"hello me"
h3 {"yo dom"}
}
```
refs only work when you're native to the platform. it doesn't make sense to gain a ref when you're not native.
## In-sync or separate?
React makes refs - and protection against dom manipulation - work by modifying the real dom while diffing the virtual dom. This lets it bind real dom elements to the virtual dom elements. Dioxus currently does not do this, instead creating a list of changes for an interpreter to apply once diffing has completed.
This behavior fit dodrio well as all dom manipulations would occur batched. The original intention for this approach was to make it faster to read out of wasm and into JS. Dodrio is essentially performing the wasm job that wasm<->js for strings does. In theory, this particular optimization is not necessary.
https://github.com/fitzgen/dodrio/issues/77
This issue/pr on the dodrio repository points to a future where elements are held on to by the virtualdom.
Can we solve events, refs, and protection against 3rd party dom mutation all in one shot?
I think we can....
every node gets a globally unique ID
abstract the real dom
```rust
trait RealDom {
type Node: RealNode;
fn get_node(&self, id: u32) -> &Self::Node;
fn get_node_mut(&mut self, id: u32) -> &mut Self::Node;
fn replace_node();
fn create_text_node();
fn create_element();
fn create_element_ns();
}
trait RealNode {
fn add_listener(&mut self, event: &str);
fn set_inner_text(&mut self, text: &str);
fn set_attr(&mut self, name, value);
fn set_class(&mut self);
fn remove_attr(&mut self);
fn downcast_mut<T>(&mut self) -> Option<&mut T>;
}
impl VirtualDom<Dom: RealDom> {
fn diff<Dom: RealDom>() {
}
}
enum VNode<'bump, 'realdom, RealDom> {
VElement {
real: &RealDom::Node
}
VText {
real: &RealDom::Node
}
}
fn main() {
let mut real_dom = websys::Document();
let virtual_dom = Dioxus::VirtualDom::new();
virtual_dom.rebuild(&mut real_dom);
loop {
let event = switch! {
real_dom.events.await => event,
virtual_dom.inner_events.await => event
};
virtual_dom.apply_event(&mut real_dom, event);
}
}
```
+18
View File
@@ -0,0 +1,18 @@
- [] Move the builder API onto NodeCtx
- [] Transition away from names and towards compile-time safe tags
- [] Fix diffing of fragments
- [] Properly integrate memoization to prevent safety issues with children
- [] Understand the issue with callbacks (outdated generations)
- [] Fix examples for core, web, ssr, and general
- [] Finish up documentation
- [] Polish the Recoil (Dirac?) API
- [] Find better names for things
- [] get the html macro up to parity with the rsx! macro
- [] put warnings in for iterating w/o keys
- [] finish up the crate for generating code blocks
- [] make progress on the docusarus-style crate for generating the websites
- [] build the docsite
- [] find a way to serialize the virtualdom completely
- [] ...some how deserialize (hydrate) the dom state?
- [] Implement controlled inputs for select and textarea
- [] ...somehow... noderefs....