Skip to content

Commit

Permalink
refactor: renamed global state to page state store
Browse files Browse the repository at this point in the history
This removes ambiguity in preparation for #119.
  • Loading branch information
arctic-hen7 committed Jan 20, 2022
1 parent 1d91aef commit 3b2401b
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 45 deletions.
10 changes: 5 additions & 5 deletions examples/basic/.perseus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use perseus::{
shell::{app_shell, get_initial_state, get_render_cfg, InitialState, ShellProps},
},
plugins::PluginAction,
state::GlobalState,
state::PageStateStore,
templates::{RouterState, TemplateNodeType},
DomNode,
};
Expand Down Expand Up @@ -65,8 +65,8 @@ pub fn run() -> Result<(), JsValue> {

// Create the router state we'll need
let router_state = RouterState::default();
// Create a global state to use
let global_state = GlobalState::default();
// Create a page state store to use
let pss = PageStateStore::default();

// Create the router we'll use for this app, based on the user's app definition
create_app_route! {
Expand All @@ -90,7 +90,7 @@ pub fn run() -> Result<(), JsValue> {
// Sycamore's reactivity is broken by a future, so we need to explicitly add the route to the reactive dependencies here
// We do need the future though (otherwise `container_rx` doesn't link to anything until it's too late)
let _ = route.get();
wasm_bindgen_futures::spawn_local(cloned!((locales, route, container_rx, router_state, global_state, translations_manager, error_pages, initial_container) => async move {
wasm_bindgen_futures::spawn_local(cloned!((locales, route, container_rx, router_state, pss, translations_manager, error_pages, initial_container) => async move {
let container_rx_elem = container_rx.get::<DomNode>().unchecked_into::<web_sys::Element>();
checkpoint("router_entry");
match &route.get().as_ref().0 {
Expand All @@ -113,7 +113,7 @@ pub fn run() -> Result<(), JsValue> {
error_pages: error_pages.clone(),
initial_container: initial_container.unwrap().clone(),
container_rx_elem: container_rx_elem.clone(),
global_state: global_state.clone()
page_state_store: pss.clone()
}
).await,
// If the user is using i18n, then they'll want to detect the locale on any paths missing a locale
Expand Down
6 changes: 3 additions & 3 deletions examples/rx_state/src/about.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use sycamore::view::View;
#[perseus::template(AboutPage)]
#[component(AboutPage<G>)]
pub fn about_page() -> View<G> {
// Get the global state manually
let global_state = get_render_ctx!().global_state;
// Get the page state store manually
let pss = get_render_ctx!().page_state_store;
// Get the state from the index page
// If the user hasn't visited there yet, this won't exist
let username = match global_state.get::<IndexPropsRx>() {
let username = match pss.get::<IndexPropsRx>() {
Some(IndexPropsRx { username }) => username,
None => Signal::new("".to_string()),
};
Expand Down
9 changes: 5 additions & 4 deletions packages/perseus-macro/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,18 @@ pub fn template_with_rx_state_impl(input: TemplateFn, attr_args: AttributeArgs)
::sycamore::prelude::view! {
#component_name(
{
// Check if properties of the reactive type are already in the global state
// Check if properties of the reactive type are already in the page state store
// If they are, we'll use them (so state persists for templates across the whole app)
let mut global_state = ::perseus::get_render_ctx!().global_state;
match global_state.get() {
// TODO Isolate this for pages
let mut pss = ::perseus::get_render_ctx!().page_state_store;
match pss.get() {
Some(old_state) => old_state,
None => {
// If there are props, they will always be provided, the compiler just doesn't know that
// If the user is using this macro, they sure should be using `#[make_rx(...)]` or similar!
let rx_props = ::serde_json::from_str::<#unrx_ty>(&props.unwrap()).unwrap().make_rx();
// They aren't in there, so insert them
global_state.add(rx_props.clone());
pss.add(rx_props.clone());
rx_props
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/perseus/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::errors::*;
use crate::locales::Locales;
use crate::router::RouterState;
use crate::state::GlobalState;
use crate::state::PageStateStore;
use crate::templates::TemplateMap;
use crate::translations_manager::TranslationsManager;
use crate::translator::Translator;
Expand Down Expand Up @@ -124,7 +124,7 @@ async fn gen_state_for_path(
translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
// Write that prerendered HTML to a static file
Expand Down Expand Up @@ -159,7 +159,7 @@ async fn gen_state_for_path(
translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
// Write that prerendered HTML to a static file
Expand Down Expand Up @@ -204,7 +204,7 @@ async fn gen_state_for_path(
translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
let head_str = template.render_head_str(None, translator);
Expand Down
4 changes: 2 additions & 2 deletions packages/perseus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ mod decode_time_str;
mod default_headers;
mod error_pages;
mod export;
mod global_state;
mod html_shell;
mod locale_detector;
mod locales;
mod log;
mod macros;
mod page_data;
mod page_state_store;
mod path_prefix;
mod router;
mod server;
Expand Down Expand Up @@ -98,7 +98,7 @@ pub mod templates {
// TODO (v0.4.0) Refactor to put several more things inside here (everything to do with generation functions)
/// Utilities for working with state.
pub mod state {
pub use crate::global_state::GlobalState;
pub use crate::page_state_store::PageStateStore;
}
/// A series of exports that should be unnecessary for nearly all uses of Perseus. These are used principally in developing alternative
/// engines.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,18 @@ use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;

/// A container for global state in Perseus. This is designed as a context store, in which one of each type can be stored. Therefore, it acts very similarly to Sycamore's context system,
/// though it's specifically designed for each template to store one reactive properties object. In theory, you could interact with this entirely independently of Perseus' state interface,
/// A container for page state in Perseus. This is designed as a context store, in which one of each type can be stored. Therefore, it acts very similarly to Sycamore's context system,
/// though it's specifically designed for each page to store one reactive properties object. In theory, you could interact with this entirely independently of Perseus' state interface,
/// though this isn't recommended.
///
/// For now, `struct`s stored in global state should have their reactivity managed by the inserter (usually the Perseus interface). However, this will change radically when Sycamore's
/// proposals for fine-grained reactivity are stabilized.
// TODO Make this work with multiple pages for a single template
#[derive(Default, Clone)]
pub struct GlobalState {
pub struct PageStateStore {
/// A map of type IDs to anything, allowing one storage of each type (each type is intended to a properties `struct` for a template). Entries must be `Clone`able becasue we assume them
/// to be `Signal`s or `struct`s composed of `Signal`s.
// Technically, this should be `Any + Clone`, but that's not possible without something like `dyn_clone`, and we don't need it because we can restrict on the methods instead!
map: Rc<RefCell<HashMap<TypeId, Box<dyn Any>>>>,
}
impl GlobalState {
impl PageStateStore {
/// Gets an element out of the state by its type.
pub fn get<T: Any + Clone>(&self) -> Option<T> {
let type_id = TypeId::of::<T>();
Expand Down
8 changes: 4 additions & 4 deletions packages/perseus/src/server/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::decode_time_str::decode_time_str;
use crate::errors::*;
use crate::page_data::PageData;
use crate::router::RouterState;
use crate::state::GlobalState;
use crate::state::PageStateStore;
use crate::stores::{ImmutableStore, MutableStore};
use crate::template::{States, Template, TemplateMap};
use crate::translations_manager::TranslationsManager;
Expand Down Expand Up @@ -82,7 +82,7 @@ async fn render_request_state(
translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
let head = template.render_head_str(state.clone(), translator);
Expand Down Expand Up @@ -173,7 +173,7 @@ async fn revalidate(
translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
let head = template.render_head_str(state.clone(), translator);
Expand Down Expand Up @@ -293,7 +293,7 @@ pub async fn get_page_for_template(
&translator,
true,
RouterState::default(),
GlobalState::default(),
PageStateStore::default(),
)
});
let head_val = template.render_head_str(state.clone(), &translator);
Expand Down
16 changes: 8 additions & 8 deletions packages/perseus/src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::error_pages::ErrorPageData;
use crate::errors::*;
use crate::page_data::PageData;
use crate::path_prefix::get_path_prefix_client;
use crate::state::GlobalState;
use crate::state::PageStateStore;
use crate::template::Template;
use crate::templates::{RouterLoadState, RouterState, TemplateNodeType};
use crate::ErrorPages;
Expand Down Expand Up @@ -224,8 +224,8 @@ pub struct ShellProps {
pub locale: String,
/// The router state.
pub router_state: RouterState,
/// The global state.
pub global_state: GlobalState,
/// The template state store.
pub page_state_store: PageStateStore,
/// A *client-side* translations manager to use (this manages caching translations).
pub translations_manager: Rc<RefCell<ClientTranslationsManager>>,
/// The error pages, for use if something fails.
Expand All @@ -246,7 +246,7 @@ pub async fn app_shell(
was_incremental_match,
locale,
router_state,
global_state,
page_state_store,
translations_manager,
error_pages,
initial_container,
Expand Down Expand Up @@ -317,7 +317,7 @@ pub async fn app_shell(
translator,
false,
router_state_2,
global_state,
page_state_store,
)
},
&container_rx_elem,
Expand All @@ -332,7 +332,7 @@ pub async fn app_shell(
translator,
false,
router_state_2,
global_state,
page_state_store,
)
},
&container_rx_elem,
Expand Down Expand Up @@ -426,7 +426,7 @@ pub async fn app_shell(
translator,
false,
router_state_2.clone(),
global_state,
page_state_store,
)
},
&container_rx_elem,
Expand All @@ -441,7 +441,7 @@ pub async fn app_shell(
translator,
false,
router_state_2,
global_state,
page_state_store,
)
},
&container_rx_elem,
Expand Down
17 changes: 9 additions & 8 deletions packages/perseus/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use crate::default_headers::default_headers;
use crate::errors::*;
use crate::global_state::GlobalState;
use crate::router::RouterState;
use crate::state::PageStateStore;
use crate::translator::Translator;
use crate::Html;
use crate::Request;
Expand All @@ -29,9 +29,10 @@ pub struct RenderCtx {
pub translator: Translator,
/// The router's state.
pub router: RouterState,
/// The global state for the app. This is a type map to which templates can add state that they need to access at a later time. Typically, interfacing with this will be done
/// through the automation of the `#[perseus::template_with_rx_state(...)]` macro, but it can be used manually as well.
pub global_state: GlobalState,
/// The page state store for the app. This is a type map to which pages can add state that they need to access later. Usually, this will be interfaced with through
/// the `#[perseus::template_with_rx_state(...)]` macro, but it can be used manually as well to get the state of one page from another (provided that the target page has already
/// been visited).
pub page_state_store: PageStateStore,
}

/// Represents all the different states that can be generated for a single template, allowing amalgamation logic to be run with the knowledge
Expand Down Expand Up @@ -239,7 +240,7 @@ impl<G: Html> Template<G> {
translator: &Translator,
is_server: bool,
router_state: RouterState,
global_state: GlobalState,
page_state_store: PageStateStore,
) -> View<G> {
view! {
// We provide the translator through context, which avoids having to define a separate variable for every translation due to Sycamore's `template!` macro taking ownership with `move` closures
Expand All @@ -248,7 +249,7 @@ impl<G: Html> Template<G> {
is_server,
translator: translator.clone(),
router: router_state,
global_state
page_state_store
},
children: || (self.template)(props)
})
Expand All @@ -266,9 +267,9 @@ impl<G: Html> Template<G> {
// It's also only ever run on the server
is_server: true,
translator: translator.clone(),
// The head string is rendered to a string, and so never has information about router or global state
// The head string is rendered to a string, and so never has information about router or page state
router: RouterState::default(),
global_state: GlobalState::default()
page_state_store: PageStateStore::default()
},
children: || (self.head)(props)
})
Expand Down

0 comments on commit 3b2401b

Please sign in to comment.