mirror of
https://github.com/leptos-rs/leptos
synced 2024-11-10 06:44:17 +00:00
prep for preview release
This commit is contained in:
parent
2239f04f6b
commit
11d134c4ba
3 changed files with 79 additions and 4 deletions
|
@ -60,8 +60,8 @@ leptos_router = { path = "./router", version = "0.7.0-preview" }
|
|||
leptos_server = { path = "./leptos_server", version = "0.7.0-preview" }
|
||||
leptos_meta = { path = "./meta", version = "0.7.0-preview" }
|
||||
oco_ref = { path = "./oco", version = "0.2" }
|
||||
or_poisoned = { path = "./or_poisoned" }
|
||||
reactive_graph = { path = "./reactive_graph" }
|
||||
or_poisoned = { path = "./or_poisoned", version = "0.1" }
|
||||
reactive_graph = { path = "./reactive_graph", version = "0.1.0-preview" }
|
||||
server_fn = { path = "./server_fn", version = "0.7.0-preview" }
|
||||
server_fn_macro = { path = "./server_fn_macro", version = "0.7.0-preview" }
|
||||
server_fn_macro_default = { path = "./server_fn/server_fn_macro_default", version = "0.7.0-preview" }
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
[package]
|
||||
name = "reactive_graph"
|
||||
version = "0.1.0-preview"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
authors = ["Greg Johnston"]
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
repository = "https://github.com/leptos-rs/leptos"
|
||||
description = "A fine-grained reactive graph for building user interfaces."
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
any_spawner = { workspace = true }
|
||||
|
|
69
reactive_graph/README.md
Normal file
69
reactive_graph/README.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
An implementation of a fine-grained reactive system.
|
||||
|
||||
Fine-grained reactivity is an approach to modeling the flow of data through an interactive
|
||||
application by composing together three categories of reactive primitives:
|
||||
|
||||
1. **Signals**: atomic units of state, which can be directly mutated.
|
||||
2. **Computations**: derived values, which cannot be mutated directly but update whenever the signals
|
||||
they depend on change. These include both synchronous and asynchronous derived values.
|
||||
3. **Effects**: side effects that synchronize the reactive system with the non-reactive world
|
||||
outside it.
|
||||
|
||||
Signals and computations are "source" nodes in the reactive graph, because an observer can
|
||||
subscribe to them to respond to changes in their values. Effects and computations are "subscriber"
|
||||
nodes, because they can listen to changes in other values.
|
||||
|
||||
```rust
|
||||
use reactive_graph::{
|
||||
computed::ArcMemo,
|
||||
effect::Effect,
|
||||
prelude::{Read, Set},
|
||||
signal::ArcRwSignal,
|
||||
};
|
||||
|
||||
let count = ArcRwSignal::new(1);
|
||||
let double_count = ArcMemo::new({
|
||||
let count = count.clone();
|
||||
move |_| *count.read() * 2
|
||||
});
|
||||
|
||||
// the effect will run once initially
|
||||
Effect::new(move |_| {
|
||||
println!("double_count = {}", *double_count.read());
|
||||
});
|
||||
|
||||
// updating `count` will propagate changes to the dependencies,
|
||||
// causing the effect to run again
|
||||
count.set(2);
|
||||
```
|
||||
|
||||
This reactivity is called "fine grained" because updating the value of a signal only affects
|
||||
the effects and computations that depend on its value, without requiring any diffing or update
|
||||
calculations for other values.
|
||||
|
||||
This model is especially suitable for building user interfaces, i.e., long-lived systems in
|
||||
which changes can begin from many different entry points. It is not particularly useful in
|
||||
"run-once" programs like a CLI.
|
||||
|
||||
## Design Principles and Assumptions
|
||||
|
||||
- **Effects are expensive.** The library is built on the assumption that the side effects
|
||||
(making a network request, rendering something to the DOM, writing to disk) are orders of
|
||||
magnitude more expensive than propagating signal updates. As a result, the algorithm is
|
||||
designed to avoid re-running side effects unnecessarily, and is willing to sacrifice a small
|
||||
amount of raw update speed to that goal.
|
||||
- **Automatic dependency tracking.** Dependencies are not specified as a compile-time list, but
|
||||
tracked at runtime. This in turn enables **dynamic dependency tracking**: subscribers
|
||||
unsubscribe from their sources between runs, which means that a subscriber that contains a
|
||||
condition branch will not re-run when dependencies update that are only used in the inactive
|
||||
branch.
|
||||
- **Asynchronous effect scheduling.** Effects are spawned as asynchronous tasks. This means
|
||||
that while updating a signal will immediately update its value, effects that depend on it
|
||||
will not run until the next "tick" of the async runtime. (This in turn means that the
|
||||
reactive system is _async runtime agnostic_: it can be used in the browser with
|
||||
`wasm-bindgen-futures`, in a native binary with `tokio`, in a GTK application with `glib`,
|
||||
etc.)
|
||||
|
||||
The reactive-graph algorithm used in this crate is based on that of
|
||||
[Reactively](https://github.com/modderme123/reactively), as described
|
||||
[in this article](https://dev.to/modderme123/super-charging-fine-grained-reactive-performance-47ph).
|
Loading…
Reference in a new issue