chore: remove `leptos_reactive` and add `reactive_graph`

This commit is contained in:
Greg Johnston 2024-02-07 21:07:54 -05:00
parent ff4cde0764
commit c8441f0f00
8 changed files with 9 additions and 395 deletions

View File

@ -1,101 +0,0 @@
use crate::{html::class::IntoClass, renderer::DomRenderer};
use leptos_reactive::{create_render_effect, Effect};
impl<F, C, R> IntoClass<R> for F
where
F: Fn() -> C + 'static,
C: IntoClass<R> + 'static,
C::State: 'static,
R: DomRenderer,
R::ClassList: 'static,
R::Element: Clone + 'static,
{
type State = Effect<C::State>;
fn to_html(self, class: &mut String) {
let value = self();
value.to_html(class);
}
fn hydrate<const FROM_SERVER: bool>(self, el: &R::Element) -> Self::State {
// TODO FROM_SERVER vs template
let el = el.clone();
create_render_effect(move |prev| {
let value = self();
if let Some(mut state) = prev {
value.rebuild(&mut state);
state
} else {
value.hydrate::<FROM_SERVER>(&el)
}
})
}
fn build(self, el: &R::Element) -> Self::State {
let el = el.to_owned();
create_render_effect(move |prev| {
let value = self();
if let Some(mut state) = prev {
value.rebuild(&mut state);
state
} else {
value.build(&el)
}
})
}
fn rebuild(self, state: &mut Self::State) {}
}
impl<F, R> IntoClass<R> for (&'static str, F)
where
F: Fn() -> bool + 'static,
R: DomRenderer,
R::ClassList: 'static,
R::Element: Clone,
{
type State = Effect<bool>;
fn to_html(self, class: &mut String) {
let (name, f) = self;
let include = f();
if include {
<&str as IntoClass<R>>::to_html(name, class);
}
}
fn hydrate<const FROM_SERVER: bool>(self, el: &R::Element) -> Self::State {
// TODO FROM_SERVER vs template
let (name, f) = self;
let class_list = R::class_list(el);
create_render_effect(move |prev| {
let include = f();
if Some(include) != prev {
if include {
R::add_class(&class_list, name);
} else {
R::remove_class(&class_list, name);
}
}
include
})
}
fn build(self, el: &R::Element) -> Self::State {
let (name, f) = self;
let class_list = R::class_list(el);
create_render_effect(move |prev| {
let include = f();
if Some(include) != prev {
if include {
R::add_class(&class_list, name);
} else {
R::remove_class(&class_list, name);
}
}
include
})
}
fn rebuild(self, state: &mut Self::State) {}
}

View File

@ -1,193 +0,0 @@
use crate::{
hydration::Cursor,
renderer::Renderer,
view::{
Mountable, Position, PositionState, Render, RenderHtml, ToTemplate,
},
};
use leptos_reactive::{create_render_effect, Effect, SignalDispose};
mod class;
mod style;
impl<F, V> ToTemplate for F
where
F: Fn() -> V,
V: ToTemplate,
{
fn to_template(
buf: &mut String,
class: &mut String,
style: &mut String,
position: &mut Position,
) {
// FIXME this seems wrong
V::to_template(buf, class, style, position)
}
}
impl<F, V, R> Render<R> for F
where
F: Fn() -> V + 'static,
V: Render<R>,
V::State: 'static,
R: Renderer,
{
type State = Effect<V::State>;
fn build(self) -> Self::State {
create_render_effect(move |prev| {
let value = self();
if let Some(mut state) = prev {
value.rebuild(&mut state);
state
} else {
value.build()
}
})
}
#[track_caller]
fn rebuild(self, state: &mut Self::State) {
crate::log(&format!(
"[REBUILDING EFFECT] Is this a mistake? {}",
std::panic::Location::caller(),
));
let old_effect = std::mem::replace(state, self.build());
old_effect.dispose();
}
}
impl<F, V, R> RenderHtml<R> for F
where
F: Fn() -> V + 'static,
V: RenderHtml<R>,
V::State: 'static,
R: Renderer + 'static,
R::Node: Clone,
R::Element: Clone,
{
const MIN_LENGTH: usize = V::MIN_LENGTH;
fn to_html_with_buf(self, buf: &mut String, position: &PositionState) {
let value = self();
value.to_html_with_buf(buf, position);
}
fn hydrate<const FROM_SERVER: bool>(
self,
cursor: &Cursor<R>,
position: &PositionState,
) -> Self::State {
let cursor = cursor.clone();
let position = position.clone();
create_render_effect(move |prev| {
let value = self();
if let Some(mut state) = prev {
value.rebuild(&mut state);
state
} else {
value.hydrate::<FROM_SERVER>(&cursor, &position)
}
})
}
}
impl<M, R> Mountable<R> for Effect<M>
where
M: Mountable<R> + 'static,
R: Renderer,
{
fn unmount(&mut self) {
self.with_value_mut(|value| {
if let Some(value) = value {
value.unmount()
}
});
}
fn mount(
&mut self,
parent: &<R as Renderer>::Element,
marker: Option<&<R as Renderer>::Node>,
) {
self.with_value_mut(|value| {
if let Some(state) = value {
state.mount(parent, marker);
}
});
}
fn insert_before_this(
&self,
parent: &<R as Renderer>::Element,
child: &mut dyn Mountable<R>,
) -> bool {
self.with_value_mut(|value| {
value
.as_mut()
.map(|value| value.insert_before_this(parent, child))
})
.flatten()
.unwrap_or(false)
}
}
/*
#[cfg(test)]
mod tests {
use crate::{
html::element::{button, main, HtmlElement},
renderer::mock_dom::MockDom,
view::Render,
};
use leptos_reactive::{create_runtime, RwSignal, SignalGet, SignalSet};
#[test]
fn create_dynamic_element() {
let rt = create_runtime();
let count = RwSignal::new(0);
let app: HtmlElement<_, _, _, MockDom> =
button((), move || count.get().to_string());
let el = app.build();
assert_eq!(el.el.to_debug_html(), "<button>0</button>");
rt.dispose();
}
#[test]
fn update_dynamic_element() {
let rt = create_runtime();
let count = RwSignal::new(0);
let app: HtmlElement<_, _, _, MockDom> =
button((), move || count.get().to_string());
let el = app.build();
assert_eq!(el.el.to_debug_html(), "<button>0</button>");
count.set(1);
assert_eq!(el.el.to_debug_html(), "<button>1</button>");
rt.dispose();
}
#[test]
fn update_dynamic_element_among_siblings() {
let rt = create_runtime();
let count = RwSignal::new(0);
let app: HtmlElement<_, _, _, MockDom> = main(
(),
button(
(),
("Hello, my ", move || count.get().to_string(), " friends."),
),
);
let el = app.build();
assert_eq!(
el.el.to_debug_html(),
"<main><button>Hello, my 0 friends.</button></main>"
);
count.set(42);
assert_eq!(
el.el.to_debug_html(),
"<main><button>Hello, my 42 friends.</button></main>"
);
rt.dispose();
}
}
*/

View File

@ -1,87 +0,0 @@
use crate::{html::style::IntoStyle, renderer::DomRenderer};
use leptos_reactive::{create_render_effect, Effect};
use std::borrow::Cow;
impl<F, S, R> IntoStyle<R> for (&'static str, F)
where
F: Fn() -> S + 'static,
S: Into<Cow<'static, str>>,
R: DomRenderer,
R::CssStyleDeclaration: Clone + 'static,
{
type State = Effect<(R::CssStyleDeclaration, Cow<'static, str>)>;
fn to_html(self, style: &mut String) {
let (name, f) = self;
let value = f();
style.push_str(name);
style.push(':');
style.push_str(&value.into());
style.push(';');
}
fn hydrate<const FROM_SERVER: bool>(self, el: &R::Element) -> Self::State {
let (name, f) = self;
// TODO FROM_SERVER vs template
let style = R::style(el);
create_render_effect(move |prev| {
let value = f().into();
if let Some(mut state) = prev {
let (style, prev): &mut (
R::CssStyleDeclaration,
Cow<'static, str>,
) = &mut state;
if &value != prev {
R::set_css_property(style, name, &value);
}
*prev = value;
state
} else {
(style.clone(), value)
}
})
}
fn build(self, el: &R::Element) -> Self::State {
todo!()
}
fn rebuild(self, state: &mut Self::State) {}
}
impl<F, C, R> IntoStyle<R> for F
where
F: Fn() -> C + 'static,
C: IntoStyle<R> + 'static,
C::State: 'static,
R: DomRenderer,
R::Element: Clone + 'static,
R::CssStyleDeclaration: Clone + 'static,
{
type State = Effect<C::State>;
fn to_html(self, class: &mut String) {
let value = self();
value.to_html(class);
}
fn hydrate<const FROM_SERVER: bool>(self, el: &R::Element) -> Self::State {
// TODO FROM_SERVER vs template
let el = el.clone();
create_render_effect(move |prev| {
let value = self();
if let Some(mut state) = prev {
value.rebuild(&mut state);
state
} else {
value.hydrate::<FROM_SERVER>(&el)
}
})
}
fn build(self, el: &R::Element) -> Self::State {
todo!()
}
fn rebuild(self, state: &mut Self::State) {}
}

View File

@ -43,13 +43,8 @@ pub use wasm_bindgen;
#[cfg(feature = "islands")]
pub use web_sys;
#[cfg(all(feature = "leptos", not(feature = "reaccy")))]
mod leptos;
#[cfg(feature = "reaccy")]
mod tachy_reaccy;
#[cfg(feature = "reaccy")]
pub use tachy_reaccy::node_ref;
#[cfg(feature = "reactive_graph")]
pub mod reactive_graph;
pub fn log(text: &str) {
web_sys::console::log_1(&JsValue::from_str(text));

View File

@ -1,6 +1,6 @@
use super::RenderEffectState;
use crate::{html::class::IntoClass, renderer::DomRenderer};
use tachy_reaccy::render_effect::RenderEffect;
use reactive_graph::effect::RenderEffect;
impl<F, C, R> IntoClass<R> for F
where

View File

@ -9,8 +9,8 @@ use crate::{
Render, RenderHtml, ToTemplate,
},
};
use reactive_graph::{computed::ScopedFuture, effect::RenderEffect};
use std::mem;
use tachy_reaccy::{async_signal::ScopedFuture, render_effect::RenderEffect};
mod class;
pub mod node_ref;

View File

@ -2,11 +2,11 @@ use crate::{
html::{element::ElementType, node_ref::NodeRefContainer},
renderer::{dom::Dom, Renderer},
};
use send_wrapper::SendWrapper;
use tachy_reaccy::{
use reactive_graph::{
signal::RwSignal,
signal_traits::{DefinedAt, SignalSet, SignalWithUntracked, Track},
traits::{DefinedAt, Set, Track, WithUntracked},
};
use send_wrapper::SendWrapper;
use wasm_bindgen::JsCast;
#[derive(Debug)]
@ -74,7 +74,7 @@ where
}
}
impl<E> SignalWithUntracked for NodeRef<E>
impl<E> WithUntracked for NodeRef<E>
where
E: ElementType,
E::Output: JsCast + Clone + 'static,

View File

@ -1,7 +1,7 @@
use super::RenderEffectState;
use crate::{html::style::IntoStyle, renderer::DomRenderer};
use reactive_graph::effect::RenderEffect;
use std::borrow::Cow;
use tachy_reaccy::render_effect::RenderEffect;
impl<F, S, R> IntoStyle<R> for (&'static str, F)
where