From bfe34c5c79a9530b4797824ce0666eeada7aa468 Mon Sep 17 00:00:00 2001 From: arctic-hen7 Date: Thu, 12 Jan 2023 06:58:42 +1100 Subject: [PATCH] feat(docs): made `perseus` client-side documentable Still need to sort out some dependency issues. --- .gitignore | 1 - packages/perseus/src/error_views.rs | 12 ++-- packages/perseus/src/i18n/mod.rs | 8 +-- packages/perseus/src/init.rs | 38 ++++++------ packages/perseus/src/lib.rs | 8 +-- packages/perseus/src/reactor/global_state.rs | 8 +-- packages/perseus/src/reactor/mod.rs | 58 +++++++++---------- packages/perseus/src/reactor/start.rs | 2 +- packages/perseus/src/reactor/state.rs | 16 ++--- packages/perseus/src/reactor/widget_state.rs | 24 ++++---- packages/perseus/src/router/mod.rs | 12 ++-- packages/perseus/src/state/global_state.rs | 12 ++-- packages/perseus/src/state/mod.rs | 20 +++---- .../src/state/rx_collections/rx_hash_map.rs | 4 +- .../rx_collections/rx_hash_map_nested.rs | 4 +- .../src/state/rx_collections/rx_vec.rs | 4 +- .../src/state/rx_collections/rx_vec_nested.rs | 4 +- packages/perseus/src/state/rx_result.rs | 4 +- packages/perseus/src/state/rx_state.rs | 6 +- packages/perseus/src/state/state_store.rs | 12 ++-- packages/perseus/src/template/capsule.rs | 24 ++++---- packages/perseus/src/template/core/mod.rs | 4 +- .../perseus/src/template/core/renderers.rs | 4 +- packages/perseus/src/template/core/setters.rs | 20 +++---- .../src/template/core/state_setters.rs | 6 +- packages/perseus/src/template/core/utils.rs | 4 +- packages/perseus/src/template/render_ctx.rs | 28 ++++----- .../perseus/src/template/widget_component.rs | 4 +- packages/perseus/src/utils/mod.rs | 14 ++--- packages/perseus/src/utils/path_prefix.rs | 2 +- packages/perseus/src/utils/render.rs | 6 +- 31 files changed, 186 insertions(+), 187 deletions(-) diff --git a/.gitignore b/.gitignore index 4576e0cf15..b58da94385 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ Cargo.lock pkg/ .tribble/ -.idea/ target_engine/ target_wasm/ diff --git a/packages/perseus/src/error_views.rs b/packages/perseus/src/error_views.rs index d4591ed5ae..95c52d279d 100644 --- a/packages/perseus/src/error_views.rs +++ b/packages/perseus/src/error_views.rs @@ -3,11 +3,11 @@ use crate::{errors::*, reactor::Reactor}; use crate::{i18n::Translator, reactor::RenderMode, state::TemplateState}; use fmterr::fmt_err; use serde::{Deserialize, Serialize}; -#[cfg(client)] +#[cfg(any(client, doc))] use std::sync::Arc; #[cfg(engine)] use sycamore::prelude::create_scope_immediate; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::{create_child_scope, try_use_context, ScopeDisposer}; use sycamore::{ prelude::{view, Scope}, @@ -49,7 +49,7 @@ pub struct ErrorViews { /// This will be extracted by the `PerseusApp` creation process and put in a /// place where it can be safely extracted. The replacement function /// will panic if called, so this should **never** be manually executed. - #[cfg(client)] + #[cfg(any(client, doc))] panic_handler: Arc< dyn Fn(Scope, ClientError, ErrorContext, ErrorPosition) -> (View, View) + Send @@ -93,7 +93,7 @@ impl ErrorViews { _ => false, } }), - #[cfg(client)] + #[cfg(any(client, doc))] panic_handler: Arc::new(handler), } } @@ -125,7 +125,7 @@ impl ErrorViews { /// Returns `true` if the given error, which must have occurred during a /// subsequent load, should be displayed as a popup, as opposed to /// occupying the entire page/widget. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) fn subsequent_err_should_be_popup(&self, err: &ClientError) -> bool { !(self.subsequent_load_determinant)(err) } @@ -171,7 +171,7 @@ impl ErrorViews { }) } } -#[cfg(client)] +#[cfg(any(client, doc))] impl ErrorViews { /// Invokes the user's handling function, producing head/body views for the /// given error. From the given scope, this will determine the diff --git a/packages/perseus/src/i18n/mod.rs b/packages/perseus/src/i18n/mod.rs index 40edd4f1b2..a53a4d2644 100644 --- a/packages/perseus/src/i18n/mod.rs +++ b/packages/perseus/src/i18n/mod.rs @@ -1,16 +1,16 @@ // This module file is controlled, because it's used as an external module as // well -#[cfg(client)] +#[cfg(any(client, doc))] mod client_translations_manager; -#[cfg(client)] +#[cfg(any(client, doc))] mod locale_detector; mod locales; mod translations_manager; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use client_translations_manager::ClientTranslationsManager; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use locale_detector::detect_locale; pub use locales::Locales; pub use translations_manager::{ diff --git a/packages/perseus/src/init.rs b/packages/perseus/src/init.rs index 144db0ab5a..e2f48e5be6 100644 --- a/packages/perseus/src/init.rs +++ b/packages/perseus/src/init.rs @@ -10,7 +10,7 @@ use crate::{ stores::MutableStore, template::{Entity, Forever, Template}, }; -#[cfg(client)] +#[cfg(any(client, doc))] use crate::{ error_views::{ErrorContext, ErrorPosition}, errors::ClientError, @@ -18,11 +18,11 @@ use crate::{ use crate::{errors::PluginError, template::Capsule}; use crate::{stores::ImmutableStore, template::EntityMap}; use futures::Future; -#[cfg(client)] +#[cfg(any(client, doc))] use std::marker::PhantomData; #[cfg(engine)] use std::pin::Pin; -#[cfg(client)] +#[cfg(any(client, doc))] use std::rc::Rc; use std::{any::TypeId, sync::Arc}; use std::{collections::HashMap, panic::PanicInfo}; @@ -160,21 +160,21 @@ pub struct PerseusAppBase { #[cfg(engine)] pub(crate) static_dir: String, /// A handler for panics on the browser-side. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) panic_handler: Option>, /// A duplicate of the app's error handling function intended for panic /// handling. This must be extracted as an owned value and provided in a /// thread-safe manner to the panic hook system. /// /// This is in an `Arc` because panic hooks are `Fn`s, not `FnOnce`s. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) panic_handler_view: Arc< dyn Fn(Scope, ClientError, ErrorContext, ErrorPosition) -> (View, View) + Send + Sync, >, // We need this on the client-side to account for the unused type parameters - #[cfg(client)] + #[cfg(any(client, doc))] _marker: PhantomData<(M, T)>, } impl std::fmt::Debug for PerseusAppBase { @@ -190,7 +190,7 @@ impl std::fmt::Debug for Perse .field("locale", &self.locales) .field("plugins", &self.plugins) .field("index_view", &self.index_view); - #[cfg(client)] + #[cfg(any(client, doc))] { return debug .field( @@ -251,7 +251,7 @@ impl PerseusAppBase { /// This is asynchronous because it creates a translations manager in the /// background. // It makes no sense to implement `Default` on this, so we silence Clippy deliberately - #[cfg(client)] + #[cfg(any(client, doc))] #[allow(clippy::new_without_default)] pub fn new() -> Self { Self::new_wasm() @@ -354,7 +354,7 @@ impl PerseusAppBase { // By default, we won't use any plugins #[cfg(engine)] plugins: Arc::new(Plugins::new()), - #[cfg(client)] + #[cfg(any(client, doc))] plugins: Rc::new(Plugins::new()), #[cfg(engine)] immutable_store: ImmutableStore::new("./dist".to_string()), @@ -366,17 +366,17 @@ impl PerseusAppBase { index_view: DFLT_INDEX_VIEW.to_string(), #[cfg(engine)] static_dir: "./static".to_string(), - #[cfg(client)] + #[cfg(any(client, doc))] panic_handler: None, - #[cfg(client)] + #[cfg(any(client, doc))] panic_handler_view: ErrorViews::unlocalized_development_default().take_panic_handler(), - #[cfg(client)] + #[cfg(any(client, doc))] _marker: PhantomData, } } /// Internal function for Wasm initialization. This should never be called /// by the user! - #[cfg(client)] + #[cfg(any(client, doc))] #[doc(hidden)] fn new_wasm() -> Self { Self { @@ -543,7 +543,7 @@ impl PerseusAppBase { // error views. #[allow(unused_mut)] pub fn error_views(mut self, mut val: ErrorViews) -> Self { - #[cfg(client)] + #[cfg(any(client, doc))] { let panic_handler = val.take_panic_handler(); self.error_views = Some(Rc::new(val)); @@ -666,7 +666,7 @@ impl PerseusAppBase { /// Sets the plugins that the app will use. See [`Plugins`] for /// further details. pub fn plugins(mut self, val: Plugins) -> Self { - #[cfg(client)] + #[cfg(any(client, doc))] { self.plugins = Rc::new(val); } @@ -771,7 +771,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn panic_handler(mut self, val: impl Fn(&PanicInfo) + Send + Sync + 'static) -> Self { - #[cfg(client)] + #[cfg(any(client, doc))] { self.panic_handler = Some(Box::new(val)); } @@ -908,7 +908,7 @@ impl PerseusAppBase { // self.entities.clone() // } // /// Gets the [`ErrorViews`] used in the app. This returns an `Rc`. - // #[cfg(client)] + // #[cfg(any(client, doc))] // pub fn get_error_views(&self) -> Rc> { // self.error_views.clone() // } @@ -978,7 +978,7 @@ impl PerseusAppBase { // self.plugins.clone() // } // /// Gets the plugins registered for the app. - // #[cfg(client)] + // #[cfg(any(client, doc))] // pub fn get_plugins(&self) -> Rc { // self.plugins.clone() // } @@ -1039,7 +1039,7 @@ impl PerseusAppBase { /// # Future panics /// If this is called more than once, the view panic handler will panic when /// called. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn take_panic_handlers( &mut self, ) -> ( diff --git a/packages/perseus/src/lib.rs b/packages/perseus/src/lib.rs index c725872dff..c8f3fbe153 100644 --- a/packages/perseus/src/lib.rs +++ b/packages/perseus/src/lib.rs @@ -52,7 +52,7 @@ pub mod template; /// General utilities that may be useful while building Perseus apps. pub mod utils; -#[cfg(all(feature = "client-helpers", client))] +#[cfg(all(feature = "client-helpers", any(client, doc)))] mod client; mod init; mod page_data; @@ -90,9 +90,9 @@ pub type Request = (); pub use perseus_macro::*; // Browser-side only -#[cfg(client)] +#[cfg(any(client, doc))] pub use crate::utils::checkpoint; -#[cfg(all(feature = "client-helpers", client))] +#[cfg(all(feature = "client-helpers", any(client, doc)))] pub use client::{run_client, ClientReturn}; /// Internal utilities for lower-level work. @@ -102,7 +102,7 @@ pub mod internal { } /// Internal utilities for logging. These are just re-exports so that users /// don't have to have `web_sys` and `wasm_bindgen` to use `web_log!`. -#[cfg(client)] +#[cfg(any(client, doc))] #[doc(hidden)] pub mod log { pub use wasm_bindgen::JsValue; diff --git a/packages/perseus/src/reactor/global_state.rs b/packages/perseus/src/reactor/global_state.rs index 6aafab7b7a..a3cc2b3998 100644 --- a/packages/perseus/src/reactor/global_state.rs +++ b/packages/perseus/src/reactor/global_state.rs @@ -1,5 +1,5 @@ use super::Reactor; -#[cfg(client)] +#[cfg(any(client, doc))] use crate::state::FrozenGlobalState; use crate::{ errors::*, @@ -96,7 +96,7 @@ impl Reactor { /// Note: on the engine-side, there is no such thing as frozen state, and /// the active state will always be empty, so this will simply return /// `None`. - #[cfg(client)] + #[cfg(any(client, doc))] fn get_held_global_state(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, @@ -141,7 +141,7 @@ impl Reactor { /// register anything in the state store. This may return an error on a /// downcast failure (which is probably the user's fault for providing /// the wrong type argument, but it's still an invariant failure). - #[cfg(client)] + #[cfg(any(client, doc))] fn get_active_global_state(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, @@ -155,7 +155,7 @@ impl Reactor { /// the thaw preferences have already been accounted for. /// /// This assumes that the app actually supports global state. - #[cfg(client)] + #[cfg(any(client, doc))] fn get_frozen_global_state_and_register(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, diff --git a/packages/perseus/src/reactor/mod.rs b/packages/perseus/src/reactor/mod.rs index 3cae0c99f9..565b0901d4 100644 --- a/packages/perseus/src/reactor/mod.rs +++ b/packages/perseus/src/reactor/mod.rs @@ -1,26 +1,26 @@ -#[cfg(client)] +#[cfg(any(client, doc))] mod error; mod global_state; -#[cfg(all(feature = "hsr", debug_assertions, client))] +#[cfg(all(feature = "hsr", debug_assertions, any(client, doc)))] mod hsr; -#[cfg(client)] +#[cfg(any(client, doc))] mod initial_load; #[cfg(engine)] mod render_mode; -#[cfg(client)] +#[cfg(any(client, doc))] mod start; mod state; -#[cfg(client)] +#[cfg(any(client, doc))] mod subsequent_load; mod widget_state; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use initial_load::InitialView; #[cfg(engine)] pub(crate) use render_mode::{RenderMode, RenderStatus}; // --- Common imports --- -#[cfg(client)] +#[cfg(any(client, doc))] use crate::template::{BrowserNodeType, EntityMap}; use crate::{ i18n::Translator, @@ -34,7 +34,7 @@ use sycamore::{ // --- Engine-side imports --- // --- Browser-side imports --- -#[cfg(client)] +#[cfg(any(client, doc))] use crate::{ error_views::ErrorViews, errors::ClientError, @@ -46,17 +46,17 @@ use crate::{ state::{FrozenApp, ThawPrefs}, stores::MutableStore, }; -#[cfg(client)] +#[cfg(any(client, doc))] use serde::{de::DeserializeOwned, Serialize}; -#[cfg(client)] +#[cfg(any(client, doc))] use serde_json::Value; -#[cfg(client)] +#[cfg(any(client, doc))] use std::{ cell::{Cell, RefCell}, collections::HashMap, rc::Rc, }; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::{ reactive::{create_rc_signal, RcSignal}, view::View, @@ -73,7 +73,7 @@ pub struct Reactor { /// preloads. pub(crate) state_store: PageStateStore, /// The router state. - #[cfg(client)] + #[cfg(any(client, doc))] pub router_state: RouterState, /// The user-provided global state, stored with similar mechanics to the /// state store, although optimised. @@ -86,41 +86,41 @@ pub struct Reactor { /// The `bool` in here will be set to `true` if this was created through /// HSR, which has slightly more lenient thawing procedures to allow for /// data model changes. - #[cfg(client)] + #[cfg(any(client, doc))] frozen_app: Rc>>, /// Whether or not this page is the very first to have been rendered since /// the browser loaded the app. This will be reset on full reloads, and is /// used internally to determine whether or not we should look for /// stored HSR state. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) is_first: Cell, /// The app's *full* render configuration. Note that a subset of this /// is contained in the [`RenderMode`] on the engine-side for widget /// rendering. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) render_cfg: HashMap, /// The app's templates and capsules for use in routing. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) entities: EntityMap, /// The app's locales. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) locales: Locales, /// The browser-side translations manager. - #[cfg(client)] + #[cfg(any(client, doc))] translations_manager: ClientTranslationsManager, /// The app's error views. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) error_views: Rc>, /// A reactive container for the current page-wide view. This will usually /// contain the contents of the current page, but it may also contain a /// page-wide error. This will be wrapped in a router. - #[cfg(client)] + #[cfg(any(client, doc))] current_view: RcSignal>, /// A reactive container for any popup errors. - #[cfg(client)] + #[cfg(any(client, doc))] popup_error_view: RcSignal>, /// The app's root div ID. - #[cfg(client)] + #[cfg(any(client, doc))] root: String, // --- Engine-side only --- @@ -137,7 +137,7 @@ pub struct Reactor { // This uses window variables set by the HTML shell, so it should never be used // on the engine-side -#[cfg(client)] +#[cfg(any(client, doc))] impl TryFrom> for Reactor { @@ -225,7 +225,7 @@ impl Reactor { /// /// On the engine-side, this will return `None` under certain error /// conditions. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn try_get_translator(&self) -> Option { self.translations_manager.get_translator() } @@ -281,7 +281,7 @@ impl Reactor { /// The possible states a window variable injected by the server/export process /// can be found in. -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) enum WindowVariable { /// It existed and coudl be deserialized into the correct type. Some(T), @@ -292,7 +292,7 @@ pub(crate) enum WindowVariable { /// string to be deserialized, found a boolean instead). Malformed, } -#[cfg(client)] +#[cfg(any(client, doc))] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with window variables that have @@ -316,7 +316,7 @@ impl WindowVariable { Self::Some(val_typed) } } -#[cfg(client)] +#[cfg(any(client, doc))] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with boolean window variables. @@ -338,7 +338,7 @@ impl WindowVariable { } } } -#[cfg(client)] +#[cfg(any(client, doc))] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with `String` window variables. diff --git a/packages/perseus/src/reactor/start.rs b/packages/perseus/src/reactor/start.rs index 107a65be22..a6c6daca57 100644 --- a/packages/perseus/src/reactor/start.rs +++ b/packages/perseus/src/reactor/start.rs @@ -153,7 +153,7 @@ impl Reactor { // This will trigger only once, and then can't be used again // That shouldn't be a problem, because we'll reload immediately Ok(_) => { - #[cfg(all(feature = "hsr"))] + #[cfg(feature = "hsr")] { let frozen_state = self.freeze(); Self::hsr_freeze(frozen_state).await; diff --git a/packages/perseus/src/reactor/state.rs b/packages/perseus/src/reactor/state.rs index a0dfe9551f..7454e29fe5 100644 --- a/packages/perseus/src/reactor/state.rs +++ b/packages/perseus/src/reactor/state.rs @@ -4,20 +4,20 @@ use crate::{ path::*, state::{AnyFreeze, MakeRx, MakeUnrx, TemplateState}, }; -#[cfg(client)] +#[cfg(any(client, doc))] use crate::{ router::RouterLoadState, state::{Freeze, FrozenApp, ThawPrefs}, }; use serde::{de::DeserializeOwned, Serialize}; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::web::Html; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore_router::navigate; // Explicitly prevent the user from trying to freeze on the engine-side -#[cfg(client)] +#[cfg(any(client, doc))] impl Freeze for Reactor { fn freeze(&self) -> String { // This constructs a `FrozenApp`, which has everything the thawing reactor will @@ -41,7 +41,7 @@ impl Freeze for Reactor { } } -#[cfg(client)] +#[cfg(any(client, doc))] impl Reactor { /// Commands Perseus to 'thaw' the app from the given frozen state. You'll /// also need to provide preferences for thawing, which allow you to control @@ -309,7 +309,7 @@ impl Reactor { /// Note: on the engine-side, there is no such thing as frozen state, and /// the active state will always be empty, so this will simply return /// `None`. - #[cfg(client)] + #[cfg(any(client, doc))] pub(super) fn get_held_state( &self, url: &PathMaybeWithLocale, @@ -360,7 +360,7 @@ impl Reactor { /// Attempts to the get the active state for a page or widget. Of course, /// this does not register anything in the state store. - #[cfg(client)] + #[cfg(any(client, doc))] fn get_active_state(&self, url: &PathMaybeWithLocale) -> Option where S: MakeRx, @@ -371,7 +371,7 @@ impl Reactor { /// Attempts to extract the frozen state for the given page from any /// currently registered frozen app, registering what it finds. This /// assumes that the thaw preferences have already been accounted for. - #[cfg(client)] + #[cfg(any(client, doc))] fn get_frozen_state_and_register( &self, url: &PathMaybeWithLocale, diff --git a/packages/perseus/src/reactor/widget_state.rs b/packages/perseus/src/reactor/widget_state.rs index 65e32f9621..ce3fbaf746 100644 --- a/packages/perseus/src/reactor/widget_state.rs +++ b/packages/perseus/src/reactor/widget_state.rs @@ -1,4 +1,4 @@ -#[cfg(client)] +#[cfg(any(client, doc))] use std::sync::Arc; use super::Reactor; @@ -15,11 +15,11 @@ use sycamore::{ web::Html, }; -#[cfg(client)] +#[cfg(any(client, doc))] use crate::template::PreloadInfo; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::create_signal; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore_futures::spawn_local_scoped; impl Reactor { @@ -38,12 +38,12 @@ impl Reactor { app_cx: Scope<'a>, path: PathMaybeWithLocale, #[allow(unused_variables)] caller_path: PathMaybeWithLocale, - #[cfg(client)] capsule_name: String, + #[cfg(any(client, doc))] capsule_name: String, template_state: TemplateState, // Empty on the browser-side props: P, - #[cfg(client)] preload_info: PreloadInfo, + #[cfg(any(client, doc))] preload_info: PreloadInfo, view_fn: F, - #[cfg(client)] fallback_fn: &Arc View + Send + Sync>, + #[cfg(any(client, doc))] fallback_fn: &Arc View + Send + Sync>, ) -> Result<(View, ScopeDisposer<'a>), ClientError> where // Note: these bounds replicate those for `.view_with_state()`, except the app lifetime is @@ -67,7 +67,7 @@ impl Reactor { } // We need to asynchronously fetch the state from the server, which doesn't work // ergonomically with the rest of the code, so we just break out entirely - #[cfg(client)] + #[cfg(any(client, doc))] None => { return { let view = create_signal(app_cx, View::empty()); @@ -162,12 +162,12 @@ impl Reactor { app_cx: Scope<'a>, path: PathMaybeWithLocale, #[allow(unused_variables)] caller_path: PathMaybeWithLocale, - #[cfg(client)] capsule_name: String, + #[cfg(any(client, doc))] capsule_name: String, template_state: TemplateState, // Empty on the browser-side props: P, - #[cfg(client)] preload_info: PreloadInfo, + #[cfg(any(client, doc))] preload_info: PreloadInfo, view_fn: F, - #[cfg(client)] fallback_fn: &Arc View + Send + Sync>, + #[cfg(any(client, doc))] fallback_fn: &Arc View + Send + Sync>, ) -> Result<(View, ScopeDisposer<'a>), ClientError> where F: Fn(Scope, S, P) -> View + Send + Sync + 'static, @@ -186,7 +186,7 @@ impl Reactor { } // We need to asynchronously fetch the state from the server, which doesn't work // ergonomically with the rest of the code, so we just break out entirely - #[cfg(client)] + #[cfg(any(client, doc))] None => { return { let view = create_signal(app_cx, View::empty()); diff --git a/packages/perseus/src/router/mod.rs b/packages/perseus/src/router/mod.rs index 244d37fafa..72920478fc 100644 --- a/packages/perseus/src/router/mod.rs +++ b/packages/perseus/src/router/mod.rs @@ -1,18 +1,18 @@ -#[cfg(client)] +#[cfg(any(client, doc))] mod app_route; mod match_route; -#[cfg(client)] +#[cfg(any(client, doc))] mod page_disposer; mod route_verdict; -#[cfg(client)] +#[cfg(any(client, doc))] mod router_state; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use app_route::PerseusRoute; pub(crate) use match_route::match_route; pub use route_verdict::{FullRouteInfo, FullRouteVerdict, RouteInfo, RouteVerdict}; -#[cfg(client)] +#[cfg(any(client, doc))] pub use router_state::{RouterLoadState, RouterState}; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use page_disposer::PageDisposer; diff --git a/packages/perseus/src/state/global_state.rs b/packages/perseus/src/state/global_state.rs index ead720418b..8a9758e56d 100644 --- a/packages/perseus/src/state/global_state.rs +++ b/packages/perseus/src/state/global_state.rs @@ -16,7 +16,7 @@ use crate::Request; use futures::Future; #[cfg(engine)] use serde::de::DeserializeOwned; -#[cfg(client)] +#[cfg(any(client, doc))] use serde::Deserialize; use serde::Serialize; use std::cell::RefCell; @@ -134,7 +134,7 @@ impl GlobalStateCreator { self } /// Adds a function to generate global state at build-time. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn build_state_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -164,7 +164,7 @@ impl GlobalStateCreator { self } /// Adds a function to generate global state at request-time. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn request_state_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -216,7 +216,7 @@ impl GlobalStateCreator { self } /// Adds a function to amalgamate build-time and request-time global state. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn amalgamate_states_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -348,7 +348,7 @@ impl std::fmt::Debug for GlobalState { } /// Frozen global state. -#[cfg(client)] +#[cfg(any(client, doc))] #[derive(Serialize, Deserialize, Debug, Clone)] pub enum FrozenGlobalState { /// There is state that should be instantiated. @@ -366,7 +366,7 @@ pub enum FrozenGlobalState { /// this purpose. Used, } -#[cfg(client)] +#[cfg(any(client, doc))] impl From<&GlobalStateType> for FrozenGlobalState { fn from(val: &GlobalStateType) -> Self { match val { diff --git a/packages/perseus/src/state/mod.rs b/packages/perseus/src/state/mod.rs index c315d59d8c..6b5d7d34c9 100644 --- a/packages/perseus/src/state/mod.rs +++ b/packages/perseus/src/state/mod.rs @@ -1,19 +1,19 @@ -#[cfg(client)] +#[cfg(any(client, doc))] mod freeze; // This has `FrozenApp` etc. mod global_state; mod rx_result; mod rx_state; mod state_generator_info; mod state_store; -#[cfg(client)] +#[cfg(any(client, doc))] mod suspense; mod template_state; // #[cfg(feature = "rx-collections")] pub mod rx_collections; -#[cfg(client)] +#[cfg(any(client, doc))] pub use freeze::{FrozenApp, PageThawPrefs, ThawPrefs}; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use global_state::FrozenGlobalState; pub use global_state::{GlobalState, GlobalStateCreator, GlobalStateType}; pub use rx_result::{RxResult, RxResultRx, SerdeInfallible}; @@ -22,18 +22,18 @@ pub use state_generator_info::{BuildPaths, StateGeneratorInfo}; pub use state_store::{PageStateStore, PssContains, PssEntry, PssState}; pub use template_state::{TemplateState, TemplateStateWithType, UnknownStateType}; -#[cfg(all(feature = "idb-freezing", client))] +#[cfg(all(feature = "idb-freezing", any(client, doc)))] mod freeze_idb; -#[cfg(all(feature = "idb-freezing", client))] +#[cfg(all(feature = "idb-freezing", any(client, doc)))] pub use freeze_idb::{IdbError, IdbFrozenStateStore}; // We'll allow live reloading (of which HSR is a subset) if it's feature-enabled // and we're in development mode -#[cfg(all(feature = "live-reload", debug_assertions, client))] +#[cfg(all(feature = "live-reload", debug_assertions, any(client, doc)))] mod live_reload; -#[cfg(all(feature = "live-reload", debug_assertions, client))] +#[cfg(all(feature = "live-reload", debug_assertions, any(client, doc)))] pub(crate) use live_reload::connect_to_reload_server; -#[cfg(all(feature = "live-reload", debug_assertions, client))] +#[cfg(all(feature = "live-reload", debug_assertions, any(client, doc)))] pub(crate) use live_reload::force_reload; -#[cfg(client)] +#[cfg(any(client, doc))] pub use suspense::{compute_nested_suspense, compute_suspense}; diff --git a/packages/perseus/src/state/rx_collections/rx_hash_map.rs b/packages/perseus/src/state/rx_collections/rx_hash_map.rs index 49d6a07118..d648058fe2 100644 --- a/packages/perseus/src/state/rx_collections/rx_hash_map.rs +++ b/packages/perseus/src/state/rx_collections/rx_hash_map.rs @@ -3,7 +3,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use std::hash::Hash; use std::ops::Deref; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -59,7 +59,7 @@ where ) } - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense(&self, _cx: Scope) {} } // --- Dereferencing --- diff --git a/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs b/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs index b35ca9300b..81c52e949d 100644 --- a/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs +++ b/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs @@ -3,7 +3,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use std::hash::Hash; use std::ops::Deref; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -56,7 +56,7 @@ where RxHashMapNested(map.into_iter().map(|(k, v)| (k, v.make_unrx())).collect()) } - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense(&self, cx: Scope) { // We do *not* want to recompute this every time the user changes the state! // (There lie infinite loops.) diff --git a/packages/perseus/src/state/rx_collections/rx_vec.rs b/packages/perseus/src/state/rx_collections/rx_vec.rs index a3202f66a7..66ccb02cd3 100644 --- a/packages/perseus/src/state/rx_collections/rx_vec.rs +++ b/packages/perseus/src/state/rx_collections/rx_vec.rs @@ -1,7 +1,7 @@ use crate::state::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -50,7 +50,7 @@ where ) } - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense(&self, _cx: Scope) {} } // --- Dereferencing --- diff --git a/packages/perseus/src/state/rx_collections/rx_vec_nested.rs b/packages/perseus/src/state/rx_collections/rx_vec_nested.rs index 4241a9fa53..3915456bf4 100644 --- a/packages/perseus/src/state/rx_collections/rx_vec_nested.rs +++ b/packages/perseus/src/state/rx_collections/rx_vec_nested.rs @@ -1,7 +1,7 @@ use crate::state::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -50,7 +50,7 @@ where RxVecNested(vec.into_iter().map(|x| x.make_unrx()).collect()) } - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense(&self, cx: Scope) { // We do *not* want to recompute this every time the user changes the state! // (There lie infinite loops.) diff --git a/packages/perseus/src/state/rx_result.rs b/packages/perseus/src/state/rx_result.rs index 641087c9ba..46ddf899ca 100644 --- a/packages/perseus/src/state/rx_result.rs +++ b/packages/perseus/src/state/rx_result.rs @@ -1,7 +1,7 @@ use super::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; use sycamore::prelude::{create_rc_signal, RcSignal}; @@ -76,7 +76,7 @@ where // fields, is fine. When that top-level field is *also* suspended, that is // very much not okay! (We would have multiple handlers operating on the // same fields, which is not a pattern I want to encourage.) - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense<'a>(&self, _cx: Scope<'a>) {} } impl Freeze for RxResultRx diff --git a/packages/perseus/src/state/rx_state.rs b/packages/perseus/src/state/rx_state.rs index 8c73cf48c5..e65af41c21 100644 --- a/packages/perseus/src/state/rx_state.rs +++ b/packages/perseus/src/state/rx_state.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; use std::any::Any; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::Scope; /// A trait for `struct`s that can be made reactive. Typically, this will be @@ -55,7 +55,7 @@ pub trait MakeUnrx { /// If you're implementing `MakeUnrx` manually, you can usually leave the /// body of this function empty unless you're using the suspended state /// system. - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense<'a>(&self, cx: Scope<'a>); } @@ -126,7 +126,7 @@ impl Deserialize<'de> + UnreactiveState + Clone> MakeUnr self.0 } // Suspense is not allowed on unreactive state - #[cfg(client)] + #[cfg(any(client, doc))] fn compute_suspense(&self, _cx: Scope) {} } // And, since the underlying type can be serialized, implement `Freeze` diff --git a/packages/perseus/src/state/state_store.rs b/packages/perseus/src/state/state_store.rs index f88b822384..8334efae15 100644 --- a/packages/perseus/src/state/state_store.rs +++ b/packages/perseus/src/state/state_store.rs @@ -2,7 +2,7 @@ use crate::errors::{ClientError, ClientInvariantError}; use crate::page_data::PageDataPartial; use crate::path::*; use crate::state::AnyFreeze; -#[cfg(client)] +#[cfg(any(client, doc))] use serde_json::Value; use std::cell::RefCell; use std::collections::HashMap; @@ -262,7 +262,7 @@ impl PageStateStore { /// # Panics /// This function will panic if the given page and widget paths are not /// already registered in the state store. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) fn declare_dependency( &self, widget_path: &PathMaybeWithLocale, @@ -291,7 +291,7 @@ impl PageStateStore { /// Note that this should generally be called through `Reactor`, to avoid /// having to manually collect the required arguments. // Note that this function bears striking resemblance to the subsequent load system! - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) async fn preload( &self, path: &PathWithoutLocale, @@ -369,7 +369,7 @@ impl PageStateStore { /// Adds the given widget to the preload list so it can be later accessed /// during the initial load render. This is not used for widgets in /// subsequently loaded pages, which are fetched separately. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) fn add_initial_widget(&self, url: PathMaybeWithLocale, state: Value) { let mut preloaded = self.preloaded.borrow_mut(); // Widgets never have heads @@ -559,12 +559,12 @@ impl PssEntry { self.head = Some(head); } /// Declares a widget that this page/widget depends on, by its path. - #[cfg(client)] + #[cfg(any(client, doc))] fn add_dependency(&mut self, path: PathMaybeWithLocale) { self.dependencies.push(path); } /// Declares a page/widget that this widget is used by, by its path. - #[cfg(client)] + #[cfg(any(client, doc))] fn add_dependent(&mut self, path: PathMaybeWithLocale) { self.dependents.push(path); } diff --git a/packages/perseus/src/template/capsule.rs b/packages/perseus/src/template/capsule.rs index 9355a9bcfe..372553d14b 100644 --- a/packages/perseus/src/template/capsule.rs +++ b/packages/perseus/src/template/capsule.rs @@ -144,7 +144,7 @@ impl Capsule { /// used for widgets. /// /// This should NOT be used to render pages! - #[cfg(client)] + #[cfg(any(client, doc))] #[allow(clippy::too_many_arguments)] pub(crate) fn render_widget_for_template_client( &self, @@ -265,9 +265,9 @@ impl CapsuleInner { { self.template_inner.view = Box::new(|_, _, _, _| panic!("attempted to call template rendering logic for widget")); - #[cfg(client)] + #[cfg(any(client, doc))] let entity_name = self.template_inner.get_path(); - #[cfg(client)] + #[cfg(any(client, doc))] let fallback_fn = self.fallback.clone(); // `Arc`ed, heaven help us self.capsule_view = Box::new( #[allow(unused_variables)] @@ -277,14 +277,14 @@ impl CapsuleInner { app_cx, path, caller_path, - #[cfg(client)] + #[cfg(any(client, doc))] entity_name.clone(), template_state, props, - #[cfg(client)] + #[cfg(any(client, doc))] preload_info, val.clone(), - #[cfg(client)] + #[cfg(any(client, doc))] fallback_fn.as_ref().unwrap(), ) }, @@ -301,9 +301,9 @@ impl CapsuleInner { { self.template_inner.view = Box::new(|_, _, _, _| panic!("attempted to call template rendering logic for widget")); - #[cfg(client)] + #[cfg(any(client, doc))] let entity_name = self.template_inner.get_path(); - #[cfg(client)] + #[cfg(any(client, doc))] let fallback_fn = self.fallback.clone(); // `Arc`ed, heaven help us self.capsule_view = Box::new( #[allow(unused_variables)] @@ -313,14 +313,14 @@ impl CapsuleInner { app_cx, path, caller_path, - #[cfg(client)] + #[cfg(any(client, doc))] entity_name.clone(), template_state, props, - #[cfg(client)] + #[cfg(any(client, doc))] preload_info, val.clone(), - #[cfg(client)] + #[cfg(any(client, doc))] fallback_fn.as_ref().unwrap(), ) }, @@ -344,7 +344,7 @@ impl CapsuleInner { // caching reactor.register_no_state(&path, true); // And declare the relationship between the widget and its caller - #[cfg(client)] + #[cfg(any(client, doc))] reactor.state_store.declare_dependency(&path, &caller_path); // Nicely, if this is a widget, this means there need be no network requests diff --git a/packages/perseus/src/template/core/mod.rs b/packages/perseus/src/template/core/mod.rs index 6e7d6753bf..b87aa24e1e 100644 --- a/packages/perseus/src/template/core/mod.rs +++ b/packages/perseus/src/template/core/mod.rs @@ -207,9 +207,9 @@ impl TemplateInner { // those feature settings through /// An alias for `DomNode` or `HydrateNode`, depending on the feature flags /// enabled. -#[cfg(all(not(feature = "hydrate"), client))] +#[cfg(all(not(feature = "hydrate"), any(client, doc)))] pub(crate) type BrowserNodeType = sycamore::prelude::DomNode; /// An alias for `DomNode` or `HydrateNode`, depending on the feature flags /// enabled. -#[cfg(all(feature = "hydrate", client))] +#[cfg(all(feature = "hydrate", any(client, doc)))] pub(crate) type BrowserNodeType = sycamore::prelude::HydrateNode; diff --git a/packages/perseus/src/template/core/renderers.rs b/packages/perseus/src/template/core/renderers.rs index a3a16a4324..c5a7f1ab8f 100644 --- a/packages/perseus/src/template/core/renderers.rs +++ b/packages/perseus/src/template/core/renderers.rs @@ -17,7 +17,7 @@ use crate::template::TemplateInner; use crate::Request; #[cfg(engine)] use http::HeaderMap; -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::prelude::ScopeDisposer; use sycamore::web::Html; #[cfg(engine)] @@ -29,7 +29,7 @@ impl TemplateInner { /// client-side ONLY. This takes in an existing global state. /// /// This should NOT be used to render widgets! - #[cfg(client)] + #[cfg(any(client, doc))] #[allow(clippy::too_many_arguments)] pub(crate) fn render_for_template_client<'a>( &self, diff --git a/packages/perseus/src/template/core/setters.rs b/packages/perseus/src/template/core/setters.rs index c702601c70..a15ce0352c 100644 --- a/packages/perseus/src/template/core/setters.rs +++ b/packages/perseus/src/template/core/setters.rs @@ -46,7 +46,7 @@ impl TemplateInner { /// /// This is for heads that do not require state. Those that do should use /// `.head_with_state()` instead. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn head(self, _val: impl Fn() + 'static) -> Self { self } @@ -70,7 +70,7 @@ impl TemplateInner { /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// does not need state. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn set_headers(self, _val: impl Fn() + 'static) -> Self { self } @@ -95,7 +95,7 @@ impl TemplateInner { self } /// Enables the *build paths* strategy with the given function. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn build_paths_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -107,7 +107,7 @@ impl TemplateInner { self } /// Enables the *incremental generation* strategy. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn incremental_generation(self) -> Self { self } @@ -143,7 +143,7 @@ impl TemplateInner { self } /// Enables the *build state* strategy with the given function. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn build_state_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -179,7 +179,7 @@ impl TemplateInner { self } /// Enables the *request state* strategy with the given function. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn request_state_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -213,7 +213,7 @@ impl TemplateInner { } /// Enables the *revalidation* strategy (logic variant) with the given /// function. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn should_revalidate_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -251,7 +251,7 @@ impl TemplateInner { /// - M: month (30 days used here, 12M ≠ 1y!), /// - y: year (365 days always, leap years ignored, if you want them add /// them as days) - #[cfg(client)] + #[cfg(any(client, doc))] pub fn revalidate_after(self, _val: I) -> Self { self } @@ -315,8 +315,8 @@ impl TemplateInner { /// and request time. The function you provide here is responsible for /// rationalizing the two into one single state to be sent to the client, /// and this will be run just after the request state function - /// completes. See [`States`] for further details. - #[cfg(client)] + /// completes. + #[cfg(any(client, doc))] pub fn amalgamate_states_fn(self, _val: impl Fn() + 'static) -> Self { self } diff --git a/packages/perseus/src/template/core/state_setters.rs b/packages/perseus/src/template/core/state_setters.rs index ea3593af2a..0c50b06c34 100644 --- a/packages/perseus/src/template/core/state_setters.rs +++ b/packages/perseus/src/template/core/state_setters.rs @@ -51,7 +51,7 @@ impl TemplateInner { let mut view = View::empty(); let disposer = ::sycamore::reactive::create_child_scope(app_cx, |child_cx| { // Compute suspended states - #[cfg(client)] + #[cfg(any(client, doc))] intermediate_state.compute_suspense(child_cx); view = val(child_cx, create_ref(child_cx, intermediate_state)); @@ -160,7 +160,7 @@ impl TemplateInner { /// /// This is for heads that do require state. Those that do not should use /// `.head()` instead. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn head_with_state(self, _val: impl Fn() + 'static) -> Self { self } @@ -208,7 +208,7 @@ impl TemplateInner { /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// requires knowing the state. - #[cfg(client)] + #[cfg(any(client, doc))] pub fn set_headers_with_state(self, _val: impl Fn() + 'static) -> Self { self } diff --git a/packages/perseus/src/template/core/utils.rs b/packages/perseus/src/template/core/utils.rs index 28b5fb3ca0..eb29af28f2 100644 --- a/packages/perseus/src/template/core/utils.rs +++ b/packages/perseus/src/template/core/utils.rs @@ -4,8 +4,8 @@ /// This exists on the engine-side for type convenience, but only has fields /// on the browser-side. pub(crate) struct PreloadInfo { - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) locale: String, - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) was_incremental_match: bool, } diff --git a/packages/perseus/src/template/render_ctx.rs b/packages/perseus/src/template/render_ctx.rs index 0ce5b7d3c7..ffc2c828e3 100644 --- a/packages/perseus/src/template/render_ctx.rs +++ b/packages/perseus/src/template/render_ctx.rs @@ -1,4 +1,4 @@ -#[cfg(client)] +#[cfg(any(client, doc))] use super::BrowserNodeType; use super::{ArcTemplateMap, TemplateState, TemplateStateWithType}; use crate::{PathMaybeWithLocale, PathWithoutLocale, errors::*}; @@ -67,7 +67,7 @@ pub struct RenderCtx { /// **Warning:** these don't exist on the engine-side! But, there, you /// should always return a build-time error rather than produce a page /// with an error in it. - #[cfg(client)] + #[cfg(any(client, doc))] pub error_pages: Rc>, // --- PRIVATE FIELDS --- // Any users accessing these are *extremely* likely to shoot themselves in the foot! @@ -75,19 +75,19 @@ pub struct RenderCtx { /// the browser loaded the app. This will be reset on full reloads, and is /// used internally to determine whether or not we should look for /// stored HSR state. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) is_first: Rc>, /// The locales, for use in routing. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) locales: crate::i18n::Locales, /// The map of all templates in the app, for use in routing. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) templates: crate::template::TemplateMap, /// The render configuration, for use in routing. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) render_cfg: Rc>, /// The client-side translations manager. - #[cfg(client)] + #[cfg(any(client, doc))] pub(crate) translations_manager: crate::i18n::ClientTranslationsManager, /// The mode we're currently rendering in. This will be used primarily in widget rendering. /// @@ -145,7 +145,7 @@ impl RenderCtx { /// /// Note also that this will automatically extract global state from page /// variables. - #[cfg(client)] // To prevent foot-shooting + #[cfg(any(client, doc))] // To prevent foot-shooting pub(crate) fn new( pss_max_size: usize, locales: crate::i18n::Locales, @@ -197,7 +197,7 @@ impl RenderCtx { /// preloading is not hardcoded, use `.try_preload()` instead. // Conveniently, we can use the lifetime mechanics of knowing that the render context // is registered on the given scope to ensure that the future works out - #[cfg(client)] + #[cfg(any(client, doc))] pub fn preload<'a, 'b: 'a>(&'b self, cx: Scope<'a>, url: &PathMaybeWithLocale) { use fmterr::fmt_err; @@ -224,7 +224,7 @@ impl RenderCtx { /// preloading is not hardcoded, use `.try_route_preload()` instead. // Conveniently, we can use the lifetime mechanics of knowing that the render context // is registered on the given scope to ensure that the future works out - #[cfg(client)] + #[cfg(any(client, doc))] pub fn route_preload<'a, 'b: 'a>(&'b self, cx: Scope<'a>, url: &PathMaybeWithLocale) { use fmterr::fmt_err; @@ -237,20 +237,20 @@ impl RenderCtx { /// A version of `.preload()` that returns a future that can resolve to an /// error. If the path you're preloading is not hardcoded, you should /// use this. - #[cfg(client)] + #[cfg(any(client, doc))] pub async fn try_preload(&self, url: &PathMaybeWithLocale) -> Result<(), ClientError> { self._preload(url, false).await } /// A version of `.route_preload()` that returns a future that can resolve /// to an error. If the path you're preloading is not hardcoded, you /// should use this. - #[cfg(client)] + #[cfg(any(client, doc))] pub async fn try_route_preload(&self, url: &PathMaybeWithLocale) -> Result<(), ClientError> { self._preload(url, true).await } /// Preloads the given URL from the server and caches it, preventing /// future network requests to fetch that page. - #[cfg(client)] + #[cfg(any(client, doc))] async fn _preload(&self, path: &PathMaybeWithLocale, is_route_preload: bool) -> Result<(), ClientError> { use crate::router::{match_route, RouteVerdict}; @@ -720,7 +720,7 @@ impl RenderCtx { /// /// Note that apps without global state will get `Some(..)` of an empty template /// state here. -#[cfg(client)] +#[cfg(any(client, doc))] fn get_global_state() -> Option { let val_opt = web_sys::window().unwrap().get("__PERSEUS_GLOBAL_STATE"); let js_obj = match val_opt { diff --git a/packages/perseus/src/template/widget_component.rs b/packages/perseus/src/template/widget_component.rs index 99427fe43a..c749d975fa 100644 --- a/packages/perseus/src/template/widget_component.rs +++ b/packages/perseus/src/template/widget_component.rs @@ -127,7 +127,7 @@ impl Capsule { }; // On the browser-side, delayed and non-delayed are the same (it just matters as // to what's been preloaded) - #[cfg(client)] + #[cfg(any(client, doc))] return { let view = self.browser_widget(cx, path, props); view @@ -137,7 +137,7 @@ impl Capsule { /// The internal browser-side logic for widgets, both delayed and not. /// /// See `.__widget()` for explanation of transmutation. - #[cfg(client)] + #[cfg(any(client, doc))] fn browser_widget(&self, cx: Scope, path: PathWithoutLocale, props: P) -> View { use crate::{ errors::ClientInvariantError, diff --git a/packages/perseus/src/utils/mod.rs b/packages/perseus/src/utils/mod.rs index f3cc723e3a..a3dcbcae36 100644 --- a/packages/perseus/src/utils/mod.rs +++ b/packages/perseus/src/utils/mod.rs @@ -2,17 +2,17 @@ mod async_fn_trait; #[cfg(engine)] mod cache_res; -#[cfg(client)] +#[cfg(any(client, doc))] mod checkpoint; mod decode_time_str; -#[cfg(client)] +#[cfg(any(client, doc))] mod fetch; mod log; #[cfg(engine)] mod minify; mod path_prefix; mod render; -#[cfg(client)] +#[cfg(any(client, doc))] mod replace_head; mod test; @@ -20,17 +20,17 @@ mod test; pub(crate) use async_fn_trait::AsyncFnReturn; #[cfg(engine)] pub use cache_res::{cache_fallible_res, cache_res}; -#[cfg(client)] +#[cfg(any(client, doc))] pub use checkpoint::checkpoint; pub use decode_time_str::{ComputedDuration, InvalidDuration, PerseusDuration}; /* These have dummy equivalents for the browser */ -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use fetch::fetch; #[cfg(engine)] pub(crate) use minify::minify; pub use path_prefix::*; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use render::render_or_hydrate; #[cfg(engine)] pub(crate) use render::ssr_fallible; -#[cfg(client)] +#[cfg(any(client, doc))] pub(crate) use replace_head::replace_head; diff --git a/packages/perseus/src/utils/path_prefix.rs b/packages/perseus/src/utils/path_prefix.rs index e428a4cfec..289c702360 100644 --- a/packages/perseus/src/utils/path_prefix.rs +++ b/packages/perseus/src/utils/path_prefix.rs @@ -17,7 +17,7 @@ pub fn get_path_prefix_server() -> String { /// Gets the path prefix to apply in the browser. This uses the HTML `` /// element, which would be required anyway to make Sycamore's router co-operate /// with a relative path hosting. -#[cfg(client)] +#[cfg(any(client, doc))] pub fn get_path_prefix_client() -> String { use wasm_bindgen::JsCast; use web_sys::{HtmlBaseElement, Url}; diff --git a/packages/perseus/src/utils/render.rs b/packages/perseus/src/utils/render.rs index d03abdb3e8..4563d18853 100644 --- a/packages/perseus/src/utils/render.rs +++ b/packages/perseus/src/utils/render.rs @@ -1,6 +1,6 @@ -#[cfg(client)] +#[cfg(any(client, doc))] use sycamore::utils::render::insert; -#[cfg(all(not(feature = "hydrate"), client))] +#[cfg(all(not(feature = "hydrate"), any(client, doc)))] use sycamore::web::DomNode; #[cfg(engine)] use sycamore::web::SsrNode; @@ -17,7 +17,7 @@ use sycamore::{prelude::Scope, view::View}; // TODO Make sure hydration will work when it's targeted at a blank canvas... // XXX This is *highly* dependent on internal Sycamore implementation // details! (TODO PR for `hydrate_to_with_scope` etc.) -#[cfg(client)] +#[cfg(any(client, doc))] #[allow(unused_variables)] pub(crate) fn render_or_hydrate( cx: Scope,