Skip to content

Commit

Permalink
Merge branch 'main' into leptos_v0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
gbj authored Jan 9, 2024
2 parents 3bd34f2 + 2d70229 commit 8c11aab
Show file tree
Hide file tree
Showing 30 changed files with 109 additions and 44 deletions.
2 changes: 2 additions & 0 deletions examples/counter/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/counter_url_query/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
1 change: 0 additions & 1 deletion examples/counters/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

[toolchain]
channel = "nightly"
1 change: 0 additions & 1 deletion examples/directives/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/error_boundary/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
4 changes: 4 additions & 0 deletions examples/errors_axum/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ This example demonstrates how Leptos Errors can work with an Axum backend on a s
## Getting Started

See the [Examples README](../README.md) for setup and run instructions.

## Quick Start

Run `cargo leptos watch` to run this example.
2 changes: 2 additions & 0 deletions examples/errors_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/fetch/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/hackernews/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/hackernews_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/hackernews_islands_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/js-framework-benchmark/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
1 change: 0 additions & 1 deletion examples/parent_child/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/router/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/session_auth_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/slots/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/ssr_modes/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/ssr_modes_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
6 changes: 0 additions & 6 deletions examples/tailwind_actix/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ cfg_if! {
use crate::app::*;
use leptos_actix::{generate_route_list, LeptosRoutes};

#[get("/style.css")]
async fn css() -> impl Responder {
actix_files::NamedFile::open_async("./style/output.css").await
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {

Expand All @@ -30,7 +25,6 @@ cfg_if! {
let site_root = &leptos_options.site_root;
let routes = &routes;
App::new()
.service(css)
.leptos_routes(leptos_options.to_owned(), routes.to_owned(), || view! { <App/> })
.service(Files::new("/", site_root))
.wrap(middleware::Compress::default())
Expand Down
1 change: 0 additions & 1 deletion examples/tailwind_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@

[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/tailwind_csr/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/todo_app_sqlite/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/todo_app_sqlite_axum/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/todo_app_sqlite_csr/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/todo_app_sqlite_viz/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
2 changes: 2 additions & 0 deletions examples/todomvc/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"
18 changes: 8 additions & 10 deletions leptos_reactive/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,12 +951,11 @@ impl RuntimeId {
false
};

let prev_observer =
SetObserverOnDrop(self, runtime.observer.take());
let prev_observer = SetObserverOnDrop(runtime.observer.take());

untracked_result = f();

runtime.observer.set(prev_observer.1);
runtime.observer.set(prev_observer.0);
std::mem::forget(prev_observer); // avoid Drop

#[cfg(debug_assertions)]
Expand Down Expand Up @@ -1371,12 +1370,12 @@ impl std::hash::Hash for Runtime {
}
}

struct SetObserverOnDrop(RuntimeId, Option<NodeId>);
struct SetObserverOnDrop(Option<NodeId>);

impl Drop for SetObserverOnDrop {
fn drop(&mut self) {
_ = with_runtime(|rt| {
rt.observer.set(self.1);
rt.observer.set(self.0);
});
}
}
Expand All @@ -1393,14 +1392,13 @@ impl Drop for SetObserverOnDrop {
)]
#[inline(always)]
pub fn batch<T>(f: impl FnOnce() -> T) -> T {
let runtime_id = Runtime::current();
with_runtime(move |runtime| {
let batching = SetBatchingOnDrop(runtime_id, runtime.batching.get());
let batching = SetBatchingOnDrop(runtime.batching.get());
runtime.batching.set(true);

let val = f();

runtime.batching.set(batching.1);
runtime.batching.set(batching.0);
std::mem::forget(batching);

runtime.run_effects();
Expand All @@ -1409,12 +1407,12 @@ pub fn batch<T>(f: impl FnOnce() -> T) -> T {
.expect("tried to run a batched update in a runtime that has been disposed")
}

struct SetBatchingOnDrop(RuntimeId, bool);
struct SetBatchingOnDrop(bool);

impl Drop for SetBatchingOnDrop {
fn drop(&mut self) {
_ = with_runtime(|rt| {
rt.batching.set(self.1);
rt.batching.set(self.0);
});
}
}
Expand Down
14 changes: 13 additions & 1 deletion router/src/components/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@ use leptos::{logging::debug_warn, server_fn::redirect::RedirectHook, *};
#[cfg(feature = "transition")]
use leptos_reactive::use_transition;
use send_wrapper::SendWrapper;
use std::{cell::RefCell, rc::Rc};
use std::{
cell::RefCell,
rc::Rc,
sync::atomic::{AtomicUsize, Ordering},
};
use thiserror::Error;
#[cfg(not(feature = "ssr"))]
use wasm_bindgen::JsCast;

static GLOBAL_ROUTERS_COUNT: AtomicUsize = AtomicUsize::new(0);

/// Provides for client-side and server-side routing. This should usually be somewhere near
/// the root of the application.
#[component]
Expand Down Expand Up @@ -70,6 +76,7 @@ pub struct RouterContext {
pub(crate) inner: Rc<RouterContextInner>,
}
pub(crate) struct RouterContextInner {
id: usize,
pub location: Location,
pub base: RouteContext,
pub possible_routes: RefCell<Option<Vec<Branch>>>,
Expand Down Expand Up @@ -184,6 +191,7 @@ impl RouterContext {
});

let inner = Rc::new(RouterContextInner {
id: GLOBAL_ROUTERS_COUNT.fetch_add(1, Ordering::SeqCst),
base_path: base_path.into_owned(),
path_stack: store_value(vec![location.pathname.get_untracked()]),
location,
Expand Down Expand Up @@ -222,6 +230,10 @@ impl RouterContext {
self.inner.base.clone()
}

pub(crate) fn id(&self) -> usize {
self.inner.id
}

/// A list of all possible routes this router can match.
pub fn possible_branches(&self) -> Vec<Branch> {
self.inner
Expand Down
45 changes: 29 additions & 16 deletions router/src/components/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
};
use leptos::{leptos_dom::HydrationCtx, *};
use std::{
borrow::Cow,
cell::{Cell, RefCell},
cmp::Reverse,
collections::HashMap,
Expand Down Expand Up @@ -76,15 +77,16 @@ pub fn Routes(
) -> impl IntoView {
let router = use_context::<RouterContext>()
.expect("<Routes/> component should be nested within a <Router/>.");
let router_id = router.id();

let base_route = router.base();
let base = base.unwrap_or_default();

Branches::initialize(&base, children());
Branches::initialize(router_id, &base, children());

#[cfg(feature = "ssr")]
if let Some(context) = use_context::<crate::PossibleBranchContext>() {
Branches::with(&base, |branches| {
Branches::with(router_id, &base, |branches| {
*context.0.borrow_mut() = branches.to_vec()
});
}
Expand All @@ -93,7 +95,8 @@ pub fn Routes(
let current_route = next_route;

let root_equal = Rc::new(Cell::new(true));
let route_states = route_states(base, &router, current_route, &root_equal);
let route_states =
route_states(router_id, base, &router, current_route, &root_equal);
provide_context(route_states);

let id = HydrationCtx::id();
Expand Down Expand Up @@ -156,15 +159,16 @@ pub fn AnimatedRoutes(
) -> impl IntoView {
let router = use_context::<RouterContext>()
.expect("<Routes/> component should be nested within a <Router/>.");
let router_id = router.id();

let base_route = router.base();
let base = base.unwrap_or_default();

Branches::initialize(&base, children());
Branches::initialize(router_id, &base, children());

#[cfg(feature = "ssr")]
if let Some(context) = use_context::<crate::PossibleBranchContext>() {
Branches::with(&base, |branches| {
Branches::with(router_id, &base, |branches| {
*context.0.borrow_mut() = branches.to_vec()
});
}
Expand Down Expand Up @@ -193,8 +197,9 @@ pub fn AnimatedRoutes(
let prev_matches = prev
.map(|(_, r)| r)
.cloned()
.map(|location| get_route_matches(&base, location));
let matches = get_route_matches(&base, next_route.clone());
.map(|location| get_route_matches(router_id, &base, location));
let matches =
get_route_matches(router_id, &base, next_route.clone());
let same_route = prev_matches
.and_then(|p| p.first().as_ref().map(|r| r.route.key.clone()))
== matches.first().as_ref().map(|r| r.route.key.clone());
Expand All @@ -221,7 +226,8 @@ pub fn AnimatedRoutes(
let current_route = create_memo(move |_| animation_and_route.get().1);

let root_equal = Rc::new(Cell::new(true));
let route_states = route_states(base, &router, current_route, &root_equal);
let route_states =
route_states(router_id, base, &router, current_route, &root_equal);

let root = root_route(base_route, route_states, root_equal);
let node_ref = create_node_ref::<html::Div>();
Expand Down Expand Up @@ -266,12 +272,13 @@ pub fn AnimatedRoutes(

pub(crate) struct Branches;

type BranchesCacheKey = (usize, Cow<'static, str>);
thread_local! {
static BRANCHES: RefCell<HashMap<String, Vec<Branch>>> = RefCell::new(HashMap::new());
static BRANCHES: RefCell<HashMap<BranchesCacheKey, Vec<Branch>>> = RefCell::new(HashMap::new());
}

impl Branches {
pub fn initialize(base: &str, children: Fragment) {
pub fn initialize(router_id: usize, base: &str, children: Fragment) {
BRANCHES.with(|branches| {
#[cfg(debug_assertions)]
{
Expand All @@ -286,7 +293,7 @@ impl Branches {
}

let mut current = branches.borrow_mut();
if !current.contains_key(base) {
if !current.contains_key(&(router_id, Cow::from(base))) {
let mut branches = Vec::new();
let children = children
.as_children()
Expand Down Expand Up @@ -316,15 +323,19 @@ impl Branches {
true,
base,
);
current.insert(base.to_string(), branches);
current.insert((router_id, Cow::Owned(base.into())), branches);
}
})
}

pub fn with<T>(base: &str, cb: impl FnOnce(&[Branch]) -> T) -> T {
pub fn with<T>(
router_id: usize,
base: &str,
cb: impl FnOnce(&[Branch]) -> T,
) -> T {
BRANCHES.with(|branches| {
let branches = branches.borrow();
let branches = branches.get(base).expect(
let branches = branches.get(&(router_id, Cow::from(base))).expect(
"Branches::initialize() should be called before \
Branches::with()",
);
Expand All @@ -334,14 +345,16 @@ impl Branches {
}

fn route_states(
router_id: usize,
base: String,
router: &RouterContext,
current_route: Memo<String>,
root_equal: &Rc<Cell<bool>>,
) -> Memo<RouterState> {
// whenever path changes, update matches
let matches =
create_memo(move |_| get_route_matches(&base, current_route.get()));
let matches = create_memo(move |_| {
get_route_matches(router_id, &base, current_route.get())
});

// iterate over the new matches, reusing old routes when they are the same
// and replacing them with new routes when they differ
Expand Down
Loading

0 comments on commit 8c11aab

Please sign in to comment.