wip: livehost bones
This commit is contained in:
1 parent
5b7887d76c
commit
7856f2b153
17 files changed
+154
-117
No files matched your search
@@ -5,6 +5,7 @@ members = [
|
|||||||
"packages/core-macro",
|
"packages/core-macro",
|
||||||
"packages/core",
|
"packages/core",
|
||||||
"packages/web",
|
"packages/web",
|
||||||
|
"packages/webview/client"
|
||||||
# "packages/router",
|
# "packages/router",
|
||||||
# "packages/ssr",
|
# "packages/ssr",
|
||||||
# "packages/webview",
|
# "packages/webview",
|
||||||
@@ -28,3 +29,5 @@ members = [
|
|||||||
# "packages/virtual-dom-rs",
|
# "packages/virtual-dom-rs",
|
||||||
# "packages/virtual-node",
|
# "packages/virtual-node",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
# About
|
<!-- # About -->
|
||||||
|
|
||||||
Dioxus is a portable, performant, and ergonomic framework for building cross-platform user experiences in Rust.
|
Dioxus is a portable, performant, and ergonomic framework for building cross-platform user experiences in Rust.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "dixous-jshost"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -306,7 +306,6 @@ unnecessary function runs
|
|||||||
Does any of this matter?
|
Does any of this matter?
|
||||||
Should we just run any component we see, immediately and imperatively? That will cause checks throughout the whole tree, no matter where the update occurred
|
Should we just run any component we see, immediately and imperatively? That will cause checks throughout the whole tree, no matter where the update occurred
|
||||||
|
|
||||||
|
|
||||||
https://calendar.perfplanet.com/2013/diff/
|
https://calendar.perfplanet.com/2013/diff/
|
||||||
|
|
||||||
Here's how react does it:
|
Here's how react does it:
|
||||||
|
|||||||
+16
-10
@@ -259,11 +259,11 @@ impl<'a> DiffMachine<'a> {
|
|||||||
let id = get_id();
|
let id = get_id();
|
||||||
*component.stable_addr.as_ref().borrow_mut() = Some(id);
|
*component.stable_addr.as_ref().borrow_mut() = Some(id);
|
||||||
self.change_list.save_known_root(id);
|
self.change_list.save_known_root(id);
|
||||||
let scope = Rc::downgrade(&component.ass_scope);
|
let scope = Rc::downgrade(&component.ass_scope);
|
||||||
self.lifecycle_events.push_back(LifeCycleEvent::Mount {
|
self.lifecycle_events.push_back(LifeCycleEvent::Mount {
|
||||||
caller: Rc::downgrade(&component.caller),
|
caller: Rc::downgrade(&component.caller),
|
||||||
id,
|
id,
|
||||||
scope
|
scope,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
VNode::Suspended => {
|
VNode::Suspended => {
|
||||||
@@ -286,20 +286,26 @@ impl<'a> DiffMachine<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
'outer1: for (_l_idx, new_l) in new.iter().enumerate() {
|
'outer1: for (_l_idx, new_l) in new.iter().enumerate() {
|
||||||
// unsafe {
|
// go through each new listener
|
||||||
// Safety relies on removing `new_l` from the registry manually at
|
// find its corresponding partner in the old list
|
||||||
// the end of its lifetime. This happens below in the `'outer2`
|
// if any characteristics changed, remove and then re-add
|
||||||
// loop, and elsewhere in diffing when removing old dom trees.
|
|
||||||
// registry.add(new_l);
|
// if nothing changed, then just move on
|
||||||
// }
|
|
||||||
let event_type = new_l.event;
|
let event_type = new_l.event;
|
||||||
|
|
||||||
for old_l in old {
|
for old_l in old {
|
||||||
if new_l.event == old_l.event {
|
if new_l.event == old_l.event {
|
||||||
|
if new_l.id != old_l.id {
|
||||||
|
self.change_list.remove_event_listener(event_type);
|
||||||
|
self.change_list
|
||||||
|
.update_event_listener(event_type, new_l.scope, new_l.id)
|
||||||
|
}
|
||||||
|
|
||||||
// if let Some(scope) = self.current_idx {
|
// if let Some(scope) = self.current_idx {
|
||||||
// let cb = CbIdx::from_gi_index(scope, l_idx);
|
// let cb = CbIdx::from_gi_index(scope, l_idx);
|
||||||
self.change_list
|
// self.change_list
|
||||||
.update_event_listener(event_type, new_l.scope, new_l.id);
|
// .update_event_listener(event_type, new_l.scope, new_l.id);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
continue 'outer1;
|
continue 'outer1;
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ impl Scope {
|
|||||||
/// This function downcasts the function pointer based on the stored props_type
|
/// This function downcasts the function pointer based on the stored props_type
|
||||||
///
|
///
|
||||||
/// Props is ?Sized because we borrow the props and don't need to know the size. P (sized) is used as a marker (unsized)
|
/// Props is ?Sized because we borrow the props and don't need to know the size. P (sized) is used as a marker (unsized)
|
||||||
pub fn run_scope<'bump>(&'bump mut self) -> Result<()> {
|
pub fn run_scope(&mut self) -> Result<()> {
|
||||||
|
// pub fn run_scope<'bump>(&'bump mut self) -> Result<()> {
|
||||||
let frame = {
|
let frame = {
|
||||||
let frame = self.frames.next();
|
let frame = self.frames.next();
|
||||||
frame.bump.reset();
|
frame.bump.reset();
|
||||||
@@ -92,7 +93,7 @@ impl Scope {
|
|||||||
|
|
||||||
let node_slot = std::rc::Rc::new(RefCell::new(None));
|
let node_slot = std::rc::Rc::new(RefCell::new(None));
|
||||||
|
|
||||||
let ctx: Context<'bump> = Context {
|
let ctx = Context {
|
||||||
arena: &self.hook_arena,
|
arena: &self.hook_arena,
|
||||||
hooks: &self.hooks,
|
hooks: &self.hooks,
|
||||||
bump: &frame.bump,
|
bump: &frame.bump,
|
||||||
@@ -107,7 +108,6 @@ impl Scope {
|
|||||||
// todo!()
|
// todo!()
|
||||||
// Note that the actual modification of the vnode head element occurs during this call
|
// Note that the actual modification of the vnode head element occurs during this call
|
||||||
let _: DomTree = (caller.as_ref())(ctx);
|
let _: DomTree = (caller.as_ref())(ctx);
|
||||||
// let _: DomTree = (self.raw_caller)(ctx, &self.props);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SAFETY ALERT
|
SAFETY ALERT
|
||||||
@@ -123,7 +123,6 @@ impl Scope {
|
|||||||
|
|
||||||
frame.head_node = node_slot
|
frame.head_node = node_slot
|
||||||
.as_ref()
|
.as_ref()
|
||||||
// .deref()
|
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.take()
|
.take()
|
||||||
.expect("Viewing did not happen");
|
.expect("Viewing did not happen");
|
||||||
|
|||||||
@@ -71,28 +71,16 @@ impl VirtualDom {
|
|||||||
/// Performs a *full* rebuild of the virtual dom, returning every edit required to generate the actual dom.
|
/// Performs a *full* rebuild of the virtual dom, returning every edit required to generate the actual dom.
|
||||||
pub fn rebuild<'s>(&'s mut self) -> Result<EditList<'s>> {
|
pub fn rebuild<'s>(&'s mut self) -> Result<EditList<'s>> {
|
||||||
// Diff from the top
|
// Diff from the top
|
||||||
let mut diff_machine = DiffMachine::new(); // partial borrow
|
let mut diff_machine = DiffMachine::new();
|
||||||
|
|
||||||
|
let very_unsafe_components = &mut self.components as *mut generational_arena::Arena<Scope>;
|
||||||
let mut component = self
|
let mut component = self
|
||||||
.components
|
.components
|
||||||
.get_mut(self.base_scope)
|
.get_mut(self.base_scope)
|
||||||
.ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))?;
|
.ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))?;
|
||||||
|
|
||||||
component.run_scope()?;
|
component.run_scope()?;
|
||||||
// let component = &*component;
|
diff_machine.diff_node(component.old_frame(), component.new_frame());
|
||||||
|
|
||||||
// get raw pointer to the arena
|
|
||||||
let very_unsafe_components = &mut self.components as *mut generational_arena::Arena<Scope>;
|
|
||||||
|
|
||||||
{
|
|
||||||
let component = self
|
|
||||||
.components
|
|
||||||
.get(self.base_scope)
|
|
||||||
.ok_or_else(|| Error::FatalInternal("Acquring base component should never fail"))?;
|
|
||||||
|
|
||||||
diff_machine.diff_node(component.old_frame(), component.new_frame());
|
|
||||||
}
|
|
||||||
// let p = &mut self.components;
|
|
||||||
// chew down the the lifecycle events until all dirty nodes are computed
|
// chew down the the lifecycle events until all dirty nodes are computed
|
||||||
while let Some(event) = diff_machine.lifecycle_events.pop_front() {
|
while let Some(event) = diff_machine.lifecycle_events.pop_front() {
|
||||||
match event {
|
match event {
|
||||||
@@ -115,27 +103,19 @@ impl VirtualDom {
|
|||||||
let real_scope = scope.upgrade().unwrap();
|
let real_scope = scope.upgrade().unwrap();
|
||||||
*real_scope.as_ref().borrow_mut() = Some(idx);
|
*real_scope.as_ref().borrow_mut() = Some(idx);
|
||||||
c.run_scope()?;
|
c.run_scope()?;
|
||||||
|
|
||||||
diff_machine.change_list.load_known_root(id);
|
diff_machine.change_list.load_known_root(id);
|
||||||
|
|
||||||
diff_machine.diff_node(c.old_frame(), c.new_frame());
|
diff_machine.diff_node(c.old_frame(), c.new_frame());
|
||||||
// diff_machine.change_list.save_known_root(id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LifeCycleEvent::PropsChanged { caller, id, scope } => {
|
LifeCycleEvent::PropsChanged { caller, id, scope } => {
|
||||||
let idx = scope.upgrade().unwrap().as_ref().borrow().unwrap();
|
let idx = scope.upgrade().unwrap().as_ref().borrow().unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
||||||
let p = &mut *(very_unsafe_components);
|
let p = &mut *(very_unsafe_components);
|
||||||
// todo, hook up the parent/child indexes properly
|
|
||||||
// let idx = p.insert_with(|f| Scope::new(caller, f, None));
|
|
||||||
let c = p.get_mut(idx).unwrap();
|
let c = p.get_mut(idx).unwrap();
|
||||||
c.update_caller(caller);
|
c.update_caller(caller);
|
||||||
c.run_scope()?;
|
c.run_scope()?;
|
||||||
// c.caller = caller;
|
|
||||||
|
|
||||||
diff_machine.change_list.load_known_root(id);
|
diff_machine.change_list.load_known_root(id);
|
||||||
|
|
||||||
diff_machine.diff_node(c.old_frame(), c.new_frame());
|
diff_machine.diff_node(c.old_frame(), c.new_frame());
|
||||||
}
|
}
|
||||||
// break 'render;
|
// break 'render;
|
||||||
|
|||||||
@@ -6,4 +6,5 @@ edition = "2018"
|
|||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
dioxus-core = { path = "../core", version = "0.1.2" }
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Livehost
|
||||||
|
|
||||||
|
Stream events from a server to a client.
|
||||||
|
|
||||||
|
This crate provides drivers for Actix, Warp, and Tide to run coupled frontend and backend.
|
||||||
|
|
||||||
|
This comes in the form of two approaches:
|
||||||
|
|
||||||
|
- tight coupling: frontend and backend are locked together
|
||||||
|
- loose coupling: hooks subscribe a component to a server using the suspense mechanism
|
||||||
|
|
||||||
|
Tight coupling is basically an implmentation of loose coupling where **all** events move through the backend connection. This coupling option has higher latency but is very simple to deploy. We use this approach for dioxus-webview where latency is minimal (hosted locally) and we want builds to be simple - no need to manually bundle a custom frontend because everything is server rendered.
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<!-- a js-only interpreter for the dioxus patch stream :) -->
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
File renamed without changes.
@@ -8,7 +8,7 @@ fn main() {
|
|||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
|
|
||||||
wasm_bindgen_futures::spawn_local(async {
|
wasm_bindgen_futures::spawn_local(async {
|
||||||
let props = ExampleProps { initial_name: "..?", blarg: vec!["abc".to_string(), "abc".to_string()]};
|
let props = ExampleProps { initial_name: "..?"};
|
||||||
WebsysRenderer::new_with_props(Example, props)
|
WebsysRenderer::new_with_props(Example, props)
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
@@ -19,13 +19,10 @@ fn main() {
|
|||||||
#[derive(PartialEq, Props)]
|
#[derive(PartialEq, Props)]
|
||||||
struct ExampleProps {
|
struct ExampleProps {
|
||||||
initial_name: &'static str,
|
initial_name: &'static str,
|
||||||
blarg: Vec<String>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Example: FC<ExampleProps> = |ctx, props| {
|
static Example: FC<ExampleProps> = |ctx, props| {
|
||||||
let (name, set_name) = use_state(&ctx, move || props.initial_name);
|
let (name, set_name) = use_state(&ctx, move || props.initial_name.to_string());
|
||||||
|
|
||||||
let sub = props.blarg.last().unwrap();
|
|
||||||
|
|
||||||
ctx.render(rsx! {
|
ctx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
@@ -39,83 +36,33 @@ static Example: FC<ExampleProps> = |ctx, props| {
|
|||||||
"Hello, {name}"
|
"Hello, {name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomButton { name: sub, set_name: Box::new(move || set_name("jack")) }
|
CustomButton { name: "Jack!", set_name: set_name }
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
CustomButton { name: "Jill!", set_name: set_name }
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
CustomButton { name: "Bob!", set_name: set_name }
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Jill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bob!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Bill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Dill!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "Crack!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "back!", set_name: Box::new(set_name) }
|
|
||||||
CustomButton { name: "cheder!", set_name: Box::new(set_name) }
|
|
||||||
// CustomButton { name: "Bill!", set_name: Box::new(move || set_name("Bill")) }
|
|
||||||
// CustomButton { name: "Reset!", set_name: Box::new(move || set_name(props.initial_name)) }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
struct ButtonProps<'src> {
|
struct ButtonProps<'src> {
|
||||||
name: &'static str,
|
name: &'src str,
|
||||||
// name: &'src str,
|
set_name: &'src dyn Fn(String)
|
||||||
set_name: Box< dyn Fn(&'static str) + 'src>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// this is an awesome component
|
||||||
|
fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree {
|
||||||
|
ctx.render(rsx!{
|
||||||
|
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 |evt| (props.set_name)(props.name.to_string())
|
||||||
|
"{props.name}"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl PartialEq for ButtonProps<'_> {
|
impl PartialEq for ButtonProps<'_> {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree {
|
|
||||||
ctx.render(rsx!{
|
|
||||||
// div {
|
|
||||||
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 |_| (props.set_name)(props.name)
|
|
||||||
"{props.name}"
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -21,4 +21,5 @@ thiserror = "1.0.23"
|
|||||||
log = "0.4.13"
|
log = "0.4.13"
|
||||||
fern = { version = "0.6.0", features = ["colored"] }
|
fern = { version = "0.6.0", features = ["colored"] }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
@@ -36,13 +36,12 @@ dioxus bundle --platform macOS
|
|||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
Because the host VirtualDOM is running in its own native process, native applications can unlock their full potential. Dioxus-webview is designed to be a 100% rust alternative to ElectronJS without the memory overhead or bloat of ElectronJS apps.
|
Because the host VirtualDOM is running in its own native process, native applications can unlock their full potential. Dioxus-webview is designed to be a 100% rust alternative to ElectronJS without the memory overhead or bloat of ElectronJS apps.
|
||||||
|
|
||||||
By bridging the native process, desktop apps can access full multithreading power, peripheral support, hardware access, and native filesystem controls without the hassle of web technologies. Our goal with Dioxus-webview is to make it easy to ship both a web and native application, and quickly see large performance boosts without having to re-write the whole stack. As the dioxus ecosystem grows, we hope to see 3rd parties providing wrappers for storage, offline mode, etc that supports both web and native technologies.
|
By bridging the native process, desktop apps can access full multithreading power, peripheral support, hardware access, and native filesystem controls without the hassle of web technologies. Our goal with Dioxus-webview is to make it easy to ship both a web and native application, and quickly see large performance boosts without having to re-write the whole stack. As the dioxus ecosystem grows, we hope to see 3rd parties providing wrappers for storage, offline mode, etc that supports both web and native technologies.
|
||||||
|
|
||||||
|
|
||||||
## Tech
|
## Tech
|
||||||
|
|
||||||
Dioxus-desktop is a pure liveview application where all of the state and event handlers are proxied through the liveview and into the native process. For pure server-based liveview, this would normally be too slow (in both render performance and latency), but because the VDom is local, desktop apps are just as fast as Electron.
|
Dioxus-desktop is a pure liveview application where all of the state and event handlers are proxied through the liveview and into the native process. For pure server-based liveview, this would normally be too slow (in both render performance and latency), but because the VDom is local, desktop apps are just as fast as Electron.
|
||||||
|
|
||||||
Dioxus-desktop leverages dioxus-liveview under the hood, but with convenience wrappers around setting up the VDom bridge, proxying events, and serving the initial WebSys-Renderer. The backend is served by Tide, so an async runtime is needed to
|
Dioxus-desktop leverages dioxus-liveview under the hood, but with convenience wrappers around setting up the VDom bridge, proxying events, and serving the initial WebSys-Renderer. The backend is served by Tide, so an async runtime *is* needed - we recommend async-std in tokio mode.
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "webview-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Jonathan Kelley <jkelleyrtp@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dioxus-core = {path = "../../core"}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
use dioxus_core::patch::Edit;
|
||||||
|
use dioxus_core::prelude::*;
|
||||||
|
|
||||||
|
static SERVER_RENDERED_KEY: &'static str = "abc123";
|
||||||
|
#[derive(Debug, PartialEq, Props)]
|
||||||
|
struct ServerRendered {
|
||||||
|
name0: String,
|
||||||
|
name1: String,
|
||||||
|
name2: String,
|
||||||
|
name3: String,
|
||||||
|
name4: String,
|
||||||
|
name5: String,
|
||||||
|
name6: String,
|
||||||
|
name7: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// connect to the host server
|
||||||
|
|
||||||
|
let server_rendered = use_server_rendered((111111, 11111, 11), SERVER_RENDERED_KEY, || {
|
||||||
|
ServerRendered {
|
||||||
|
name0: "abc".to_string(),
|
||||||
|
name1: "abc".to_string(),
|
||||||
|
name2: "abc".to_string(),
|
||||||
|
name3: "abc".to_string(),
|
||||||
|
name4: "abc".to_string(),
|
||||||
|
name5: "abc".to_string(),
|
||||||
|
name6: "abc".to_string(),
|
||||||
|
name7: "abc".to_string(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let handler = dioxus_liveview::new_handler()
|
||||||
|
.from_directory("abc123") // serve a given directory as the root
|
||||||
|
.with_context(|| SomeContext {}) // build out a new context for all of the server-rendered components to share
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props: &ServerRendered| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
.with_route(SERVER_RENDERED_KEY, |ctx, props| {
|
||||||
|
//
|
||||||
|
})
|
||||||
|
// depend on the framework, build a different type of handler
|
||||||
|
// there are instructions on how to integrate this the various rusty web frameworks in the guide
|
||||||
|
.build();
|
||||||
|
|
||||||
|
server.get("abc", handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_server_rendered<F: Properties>(_p: impl PartialEq, name: &'static str, f: impl Fn() -> F) {}
|
||||||
Reference in new issue
Block a user