1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#![doc = include_str!("../README.proj.md")]
/*!
## Features

- `translator-fluent` --- enables internationalization using [Fluent](https://projectfluent.org)
- `macros` (default) --- adds support for macros that will make your life much easier
- `dflt_engine` (default) --- adds support for the default engine-side mechanics (you would only not want this in extremely niche use-cases)
- `client_helpers` (default) --- adds useful helpers for managing the browser-side
- `hydrate` --- enables Sycamore's *experimental* hydration system (if you experience odd issues, try disabling this)
- `preload-wasm-on-redirect` --- *experimentally* preloads the Wasm bundle for locale redirections (this only partially works right now)
- `idb-freezing` --- enables utilities for freezing your app's state to IndexedDB in the browser (see the book)
- `live-reload` (default) --- enables reloading the browser automatically when you make changes to your app
- `hsr` (default) --- enables *hot state reloading*, which reloads the state of your app right before you made code changes in development, allowing you to pick up where you left off

## Packages

This is the API documentation for the core `perseus` package, which underlies all Perseus apps. Note that Perseus mostly uses [the book](https://framesurge.sh/perseus/en-US) for
documentation, and this should mostly be used as a secondary reference source. You can also find full usage examples [here](https://github.com/framesurge/perseus/tree/main/examples).
*/

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![recursion_limit = "256"] // TODO Do we need this anymore?

/// Utilities for working with the engine-side, particularly with regards to
/// setting up the entrypoint for your app's build/export/server processes.
#[cfg(engine)]
pub mod engine;
/// Utilities surrounding `ErrorViews` and their management.
pub mod error_views;
pub mod errors;
/// Utilities for internationalization, the process of making your app available
/// in multiple languages.
pub mod i18n;
/// Utilities for working with plugins.
pub mod plugins;
/// Utilities for working with the router. Note that you should only have to use
/// these when waiting for a page transition in normal use-cases.
pub mod router;
/// Utilities for working with the server. These are fairly low-level, and
/// are intended for use by those developing new server integrations.
#[cfg(engine)]
pub mod server;
/// Utilities for working with Perseus' state platform.
pub mod state;
/// Utilities for working with immutable and mutable stores. See
/// [`stores::ImmutableStore`] and [`stores::MutableStore`] for details.
pub mod stores;
/// Utilities for working with templates and state generation. This is by far
/// the module you'll probably access the most.
pub mod template;
/// General utilities that may be useful while building Perseus apps.
pub mod utils;

/// Utilities for initializing the Perseus client.
#[cfg(all(feature = "client-helpers", any(client, doc)))]
pub mod client;
mod init;
mod page_data;
/// Utilities for working with typed paths.
pub mod path;
/// The core of the Perseus browser-side system. This is used on the engine-side
/// as well for rendering.
pub mod reactor;
mod translator;
/// The core of the Perseus state generation system.
#[cfg(engine)]
pub mod turbine;

// The rest of this file is devoted to module structuring
// Re-exports
#[cfg(engine)]
pub use http;
#[cfg(engine)]
pub use http::Request as HttpRequest;

/// All HTTP requests use empty bodies for simplicity of passing them around.
/// They'll never need payloads (value in path requested).
///
/// **Warning:** on the browser-side, this is defined as `()`.
#[cfg(engine)]
pub type Request = HttpRequest<()>;
/// All HTTP requests use empty bodies for simplicity of passing them around.
/// They'll never need payloads (value in path requested).
///
/// **Warning:** on the browser-side, this is defined as `()`.
#[cfg(client)]
pub type Request = ();

#[cfg(feature = "macros")]
pub use perseus_macro::*;

/// Internal utilities for lower-level work.
#[cfg(engine)]
pub mod internal {
    pub use crate::page_data::*;
}
/// 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(any(client, doc))]
#[doc(hidden)]
pub mod log {
    pub use wasm_bindgen::JsValue;
    pub use web_sys::console::log_1 as log_js_value;
}

/// An alias for `DomNode`, `HydrateNode`, or `SsrNode`, depending on the
/// `hydrate` feature flag and compilation target.
///
/// You **should not** use this in your return types (e.g.
/// `View<PerseusNodeType>`), there you should use a `G: Html` generic.
/// This is intended for `lazy_static!`s and the like, for capsules. See
/// the book and capsule examples for further details.
#[cfg(engine)]
pub type PerseusNodeType = sycamore::web::SsrNode;
/// An alias for `DomNode`, `HydrateNode`, or `SsrNode`, depending on the
/// `hydrate` feature flag and compilation target.
///
/// You **should not** use this in your return types (e.g.
/// `View<PerseusNodeType>`), there you should use a `G: Html` generic.
/// This is intended for `lazy_static!`s and the like, for capsules. See
/// the book and capsule examples for further details.
#[cfg(all(client, not(feature = "hydrate")))]
pub type PerseusNodeType = sycamore::web::DomNode;
/// An alias for `DomNode`, `HydrateNode`, or `SsrNode`, depending on the
/// `hydrate` feature flag and compilation target.
///
/// You **should not** use this in your return types (e.g.
/// `View<PerseusNodeType>`), there you should use a `G: Html` generic.
/// This is intended for `lazy_static!`s and the like, for capsules. See
/// the book and capsule examples for further details.
#[cfg(all(client, feature = "hydrate"))]
pub type PerseusNodeType = sycamore::web::HydrateNode;

/// A series of imports needed by most Perseus apps, in some form. This should
/// be used in conjunction with the Sycamore prelude.
pub mod prelude {
    pub use crate::error_views::ErrorViews;
    // Target-gating doesn't matter, because the prelude is intended to be used all
    // at once
    #[cfg(engine)]
    pub use crate::errors::{BlamedError, ErrorBlame};
    pub use crate::init::*;
    pub use crate::reactor::Reactor;
    pub use crate::state::{BuildPaths, RxResult, RxResultRx, SerdeInfallible, StateGeneratorInfo};
    pub use crate::template::{Capsule, Template};
    pub use sycamore::web::Html;
    pub use sycamore_router::{navigate, navigate_replace};

    #[cfg(engine)]
    pub use crate::utils::{cache_fallible_res, cache_res};
    pub use crate::web_log;
    #[cfg(any(feature = "translator-fluent", feature = "translator-lightweight"))]
    pub use crate::{link, t};
    pub use crate::{PerseusNodeType, Request};
    #[cfg(feature = "macros")]
    pub use perseus_macro::*;
    pub use sycamore_futures::spawn_local_scoped;

    #[cfg(any(client, doc))]
    pub use crate::utils::checkpoint;
}