Skip to content

Commit

Permalink
fix: fixed exporting with typed options system
Browse files Browse the repository at this point in the history
  • Loading branch information
arctic-hen7 committed Mar 29, 2022
1 parent 0e6eb5d commit 18f54a9
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 22 deletions.
9 changes: 7 additions & 2 deletions examples/core/basic/.perseus/builder/src/bin/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use perseus::{
export::{export_app, ExportProps},
get_path_prefix_server,
},
PluginAction, SsrNode,
PerseusApp, PluginAction, SsrNode,
};
use perseus_engine as app;
use std::fs;
Expand Down Expand Up @@ -76,7 +76,8 @@ async fn build_and_export() -> i32 {
}
};
let templates_map = app.get_templates_map();
let index_view = app.get_index_view().await;
let index_view_str = app.get_index_view_str();
let root_id = app.get_root();
// This consumes `self`, so we get it finally
let translations_manager = app.get_translations_manager().await;

Expand Down Expand Up @@ -107,6 +108,10 @@ async fn build_and_export() -> i32 {
.export_actions
.after_successful_build
.run((), plugins.get_plugin_data());
// The app has now been built, so we can safely instantiate the HTML shell (which needs access to the render config, generated in the above build step)
// It doesn't matter if the type parameters here are wrong, this function doesn't use them
let index_view =
PerseusApp::get_html_shell(index_view_str, &root_id, &immutable_store, &plugins).await;
// Turn the build artifacts into self-contained static files
let export_res = export_app(ExportProps {
templates: &templates_map,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use fmterr::fmt_err;
use perseus::{internal::serve::build_error_page, PluginAction, SsrNode};
use perseus::{internal::serve::build_error_page, PerseusApp, PluginAction, SsrNode};
use perseus_engine as app;
use std::{env, fs};

Expand All @@ -18,7 +18,13 @@ async fn real_main() -> i32 {

let error_pages = app.get_error_pages();
// Prepare the HTML shell
let html_shell = app.get_index_view().await;
let index_view_str = app.get_index_view_str();
let root_id = app.get_root();
let immutable_store = app.get_immutable_store();
// We assume the app has already been built before running this (so the render config must be available)
// It doesn't matter if the type parameters here are wrong, this function doesn't use them
let html_shell =
PerseusApp::get_html_shell(index_view_str, &root_id, &immutable_store, &plugins).await;
// Get the error code to build from the arguments to this executable
let args = env::args().collect::<Vec<String>>();
let err_code_to_build_for = match args.get(1) {
Expand Down Expand Up @@ -50,6 +56,7 @@ async fn real_main() -> i32 {
(err_code_to_build_for, output.to_string()),
plugins.get_plugin_data(),
);

// Build that error page as the server does
let err_page_str = build_error_page(
"",
Expand Down
10 changes: 9 additions & 1 deletion examples/core/basic/.perseus/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use perseus::internal::i18n::TranslationsManager;
use perseus::internal::serve::{ServerOptions, ServerProps};
use perseus::plugins::PluginAction;
use perseus::stores::MutableStore;
use perseus::PerseusApp;
use perseus::SsrNode;
use perseus_engine as app;
use std::env;
Expand Down Expand Up @@ -106,9 +107,16 @@ fn get_props(is_standalone: bool) -> ServerProps<impl MutableStore, impl Transla
let static_aliases = app.get_static_aliases();
let templates_map = app.get_atomic_templates_map();
let error_pages = app.get_error_pages();
let index_view = block_on(app.get_index_view());
let index_view_str = app.get_index_view_str();
// Generate the global state
let global_state_creator = app.get_global_state_creator();
// By the time this binary is being run, the app has already been built be the CLI (hopefully!), so we can depend on access to hte render config
let index_view = block_on(PerseusApp::get_html_shell(
index_view_str,
&app_root,
&immutable_store,
&plugins,
));

let opts = ServerOptions {
// We don't support setting some attributes from `wasm-pack` through plugins/`define_app!` because that would require CLI changes as well (a job for an alternative engine)
Expand Down
41 changes: 24 additions & 17 deletions packages/perseus/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,39 +323,46 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
.run((), self.plugins.get_plugin_data())
.unwrap_or_else(|| self.root.to_string())
}
/// Gets the index view. This is asynchronous because it constructs an HTML shell, which invovles fetching the configuration of pages.
/// Gets the index view as a string, without generating an HTML shell (pass this into `::get_html_shell()` to do that).
///
/// Note that this automatically adds `<!DOCTYPE html>` to the start of the HTMl shell produced, which can only be overriden with a control plugin (though you should really never do this
/// in Perseus, which targets HTML on the web).
#[cfg(feature = "server-side")]
pub async fn get_index_view(&self) -> HtmlShell {
// TODO Allow plugin modification of this
pub fn get_index_view_str(&self) -> String {
// We have to add an HTML document type declaration, otherwise the browser could think it's literally anything! (This shouldn't be a problem, but it could be in 100 years...)
let index_view_str = format!("<!DOCTYPE html>\n{}", self.index_view);
format!("<!DOCTYPE html>\n{}", self.index_view)
}
/// Gets an HTML shell from an index view string. This is broken out so that it can be executed after the app has been built (which requries getting the translations manager, consuming
/// `self`). As inconvenient as this is, it's necessitated, otherwise exporting would try to access the built app before it had actually been built.
#[cfg(feature = "server-side")]
pub async fn get_html_shell(
index_view_str: String,
root: &str,
immutable_store: &ImmutableStore,
plugins: &Plugins<G>,
) -> HtmlShell {
// Construct an HTML shell
let mut html_shell = HtmlShell::new(
index_view_str,
&self.get_root(),
root,
// TODO Handle this properly (good enough for now because that's what we weere already doing)
&get_render_cfg(&self.get_immutable_store())
&get_render_cfg(immutable_store)
.await
.expect("Couldn't get render configuration!"),
&get_path_prefix_server(),
);

// Apply the myriad plugin actions to the HTML shell (replacing the whole thing first if need be)
let shell_str = self
.plugins
let shell_str = plugins
.control_actions
.settings_actions
.html_shell_actions
.set_shell
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.unwrap_or(html_shell.shell);
html_shell.shell = shell_str;
// For convenience, we alias the HTML shell functional actions
let hsf_actions = &self
.plugins
let hsf_actions = &plugins
.functional_actions
.settings_actions
.html_shell_actions;
Expand All @@ -364,7 +371,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.head_before_boundary.push(
hsf_actions
.add_to_head_before_boundary
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand All @@ -373,7 +380,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.scripts_before_boundary.push(
hsf_actions
.add_to_scripts_before_boundary
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand All @@ -382,7 +389,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.head_after_boundary.push(
hsf_actions
.add_to_head_after_boundary
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand All @@ -391,7 +398,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.scripts_after_boundary.push(
hsf_actions
.add_to_scripts_after_boundary
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand All @@ -400,7 +407,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.before_content.push(
hsf_actions
.add_to_before_content
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand All @@ -409,7 +416,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
html_shell.after_content.push(
hsf_actions
.add_to_after_content
.run((), self.plugins.get_plugin_data())
.run((), plugins.get_plugin_data())
.values()
.flatten()
.cloned()
Expand Down

0 comments on commit 18f54a9

Please sign in to comment.