Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed options system #130

Merged
merged 10 commits into from
Mar 21, 2022
16 changes: 8 additions & 8 deletions examples/comprehensive/tiny/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use perseus::{define_app, ErrorPages, Template};
use perseus::{Html, PerseusApp, Template};
use sycamore::view;
define_app! {
templates: [
Template::<G>::new("index").template(|_| view! {
p { "Hello World!" }

pub fn main<G: Html>() -> PerseusApp<G> {
PerseusApp::new().template(|| {
Template::new("index").template(|_| {
view! {
p { "Hello World!" }
}
})
],
error_pages: ErrorPages::new(|url, status, err, _| view! {
p { (format!("An error with HTTP code {} occurred at '{}': '{}'.", status, url, err)) }
})
}
1 change: 1 addition & 0 deletions examples/core/basic/.perseus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ web-sys = { version = "0.3", features = ["Event", "Headers", "Request", "Request
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
console_error_panic_hook = "0.1.6"
lazy_static = "1"

# This section is needed for Wasm Pack (which we use instead of Trunk for flexibility)
[lib]
Expand Down
24 changes: 12 additions & 12 deletions examples/core/basic/.perseus/builder/src/bin/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ use perseus::{
internal::build::{build_app, BuildProps},
PluginAction, SsrNode,
};
use perseus_engine::app::{
get_global_state_creator, get_immutable_store, get_locales, get_mutable_store, get_plugins,
get_templates_map, get_translations_manager,
};
use perseus_engine as app;

#[tokio::main]
async fn main() {
Expand All @@ -17,21 +14,20 @@ async fn main() {
async fn real_main() -> i32 {
// We want to be working in the root of `.perseus/`
std::env::set_current_dir("../").unwrap();
let plugins = get_plugins::<SsrNode>();
let app = app::main::<SsrNode>();
let plugins = app.get_plugins();

plugins
.functional_actions
.build_actions
.before_build
.run((), plugins.get_plugin_data());

let immutable_store = get_immutable_store(&plugins);
let mutable_store = get_mutable_store();
// We can't proceed without a translations manager
let translations_manager = get_translations_manager().await;
let locales = get_locales(&plugins);
let immutable_store = app.get_immutable_store();
let mutable_store = app.get_mutable_store();
let locales = app.get_locales();
// Generate the global state
let gsc = get_global_state_creator();
let gsc = app.get_global_state_creator();
let global_state = match gsc.get_build_state().await {
Ok(global_state) => global_state,
Err(err) => {
Expand All @@ -48,7 +44,11 @@ async fn real_main() -> i32 {

// Build the site for all the common locales (done in parallel)
// All these parameters can be modified by `define_app!` and plugins, so there's no point in having a plugin opportunity here
let templates_map = get_templates_map::<SsrNode>(&plugins);
let templates_map = app.get_templates_map();

// We have to get the translations manager last, because it consumes everything
let translations_manager = app.get_translations_manager().await;

let res = build_app(BuildProps {
templates: &templates_map,
locales: &locales,
Expand Down
37 changes: 19 additions & 18 deletions examples/core/basic/.perseus/builder/src/bin/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ use perseus::{
},
PluginAction, SsrNode,
};
use perseus_engine::app::{
get_app_root, get_global_state_creator, get_immutable_store, get_locales, get_mutable_store,
get_plugins, get_static_aliases, get_templates_map, get_translations_manager,
};
use perseus_engine as app;
use std::fs;
use std::path::PathBuf;

Expand All @@ -24,8 +21,9 @@ async fn main() {
async fn real_main() -> i32 {
// We want to be working in the root of `.perseus/`
std::env::set_current_dir("../").unwrap();
let app = app::main::<SsrNode>();

let plugins = get_plugins::<SsrNode>();
let plugins = app.get_plugins();

// Building and exporting must be sequential, but that can be done in parallel with static directory/alias copying
let exit_code = build_and_export().await;
Expand All @@ -49,21 +47,21 @@ async fn real_main() -> i32 {
}

async fn build_and_export() -> i32 {
let plugins = get_plugins::<SsrNode>();
let app = app::main::<SsrNode>();
let plugins = app.get_plugins();

plugins
.functional_actions
.build_actions
.before_build
.run((), plugins.get_plugin_data());

let immutable_store = get_immutable_store(&plugins);
let immutable_store = app.get_immutable_store();
// We don't need this in exporting, but the build process does
let mutable_store = get_mutable_store();
let translations_manager = get_translations_manager().await;
let locales = get_locales(&plugins);
let mutable_store = app.get_mutable_store();
let locales = app.get_locales();
// Generate the global state
let gsc = get_global_state_creator();
let gsc = app.get_global_state_creator();
let global_state = match gsc.get_build_state().await {
Ok(global_state) => global_state,
Err(err) => {
Expand All @@ -77,10 +75,13 @@ async fn build_and_export() -> i32 {
return 1;
}
};
let templates_map = app.get_templates_map();
let index_view = app.get_index_view().await;
// This consumes `self`, so we get it finally
let translations_manager = app.get_translations_manager().await;

// Build the site for all the common locales (done in parallel), denying any non-exportable features
// We need to build and generate those artifacts before we can proceed on to exporting
let templates_map = get_templates_map::<SsrNode>(&plugins);
let build_res = build_app(BuildProps {
templates: &templates_map,
locales: &locales,
Expand All @@ -107,12 +108,10 @@ async fn build_and_export() -> i32 {
.after_successful_build
.run((), plugins.get_plugin_data());
// Turn the build artifacts into self-contained static files
let app_root = get_app_root(&plugins);
let export_res = export_app(ExportProps {
templates: &templates_map,
html_shell_path: "../index.html",
html_shell: index_view,
locales: &locales,
root_id: &app_root,
immutable_store: &immutable_store,
translations_manager: &translations_manager,
path_prefix: get_path_prefix_server(),
Expand All @@ -134,12 +133,13 @@ async fn build_and_export() -> i32 {
}

fn copy_static_dir() -> i32 {
let plugins = get_plugins::<SsrNode>();
let app = app::main::<SsrNode>();
let plugins = app.get_plugins();
// Loop through any static aliases and copy them in too
// Unlike with the server, these could override pages!
// We'll copy from the alias to the path (it could be a directory or a file)
// Remember: `alias` has a leading `/`!
for (alias, path) in get_static_aliases(&plugins) {
for (alias, path) in app.get_static_aliases() {
let from = PathBuf::from(path);
let to = format!("dist/exported{}", alias);

Expand Down Expand Up @@ -180,7 +180,8 @@ fn copy_static_dir() -> i32 {
}

fn copy_static_aliases() -> i32 {
let plugins = get_plugins::<SsrNode>();
let app = app::main::<SsrNode>();
let plugins = app.get_plugins();
// Copy the `static` directory into the export package if it exists
// If the user wants extra, they can use static aliases, plugins are unnecessary here
let static_dir = PathBuf::from("../static");
Expand Down
33 changes: 6 additions & 27 deletions examples/core/basic/.perseus/builder/src/bin/export_error_page.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use fmterr::fmt_err;
use perseus::{
internal::{
get_path_prefix_server,
serve::{build_error_page, get_render_cfg, HtmlShell},
},
PluginAction, SsrNode,
};
use perseus_engine::app::{get_app_root, get_error_pages, get_immutable_store, get_plugins};
use perseus::{internal::serve::build_error_page, PluginAction, SsrNode};
use perseus_engine as app;
use std::{env, fs};

#[tokio::main]
Expand All @@ -18,28 +12,13 @@ async fn main() {
async fn real_main() -> i32 {
// We want to be working in the root of `.perseus/`
env::set_current_dir("../").unwrap();
let app = app::main::<SsrNode>();

let plugins = get_plugins::<SsrNode>();
let plugins = app.get_plugins();

let error_pages = get_error_pages(&plugins);
let root_id = get_app_root(&plugins);
let immutable_store = get_immutable_store(&plugins);
let render_cfg = match get_render_cfg(&immutable_store).await {
Ok(render_cfg) => render_cfg,
Err(err) => {
eprintln!("{}", fmt_err(&err));
return 1;
}
};
let error_pages = app.get_error_pages();
// Prepare the HTML shell
let html = match fs::read_to_string("../index.html") {
Ok(html) => html,
Err(err) => {
eprintln!("{}", fmt_err(&err));
return 1;
}
};
let html_shell = HtmlShell::new(html, &root_id, &render_cfg, &get_path_prefix_server());
let html_shell = app.get_index_view().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
4 changes: 2 additions & 2 deletions examples/core/basic/.perseus/builder/src/bin/tinker.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use perseus::{plugins::PluginAction, SsrNode};
use perseus_engine::app::get_plugins;
use perseus_engine as app;

fn main() {
let exit_code = real_main();
Expand All @@ -10,7 +10,7 @@ fn real_main() -> i32 {
// We want to be working in the root of `.perseus/`
std::env::set_current_dir("../").unwrap();

let plugins = get_plugins::<SsrNode>();
let plugins = app::main::<SsrNode>().get_plugins();
// Run all the tinker actions
// Note: this is deliberately synchronous, tinker actions that need a multithreaded async runtime should probably
// be making their own engines!
Expand Down
36 changes: 17 additions & 19 deletions examples/core/basic/.perseus/server/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ use perseus::internal::serve::{ServerOptions, ServerProps};
use perseus::plugins::PluginAction;
use perseus::stores::MutableStore;
use perseus::SsrNode;
use perseus_engine::app::{
get_app_root, get_error_pages, get_global_state_creator, get_immutable_store, get_locales,
get_mutable_store, get_plugins, get_static_aliases, get_templates_map_atomic,
get_translations_manager,
};
use perseus_engine as app;
use std::env;
use std::fs;

Expand Down Expand Up @@ -88,7 +84,8 @@ fn get_host_and_port() -> (String, u16) {

/// Gets the properties to pass to the server.
fn get_props(is_standalone: bool) -> ServerProps<impl MutableStore, impl TranslationsManager> {
let plugins = get_plugins::<SsrNode>();
let app = app::main::<SsrNode>();
let plugins = app.get_plugins();

plugins
.functional_actions
Expand All @@ -97,24 +94,25 @@ fn get_props(is_standalone: bool) -> ServerProps<impl MutableStore, impl Transla
.run((), plugins.get_plugin_data());

// This allows us to operate inside `.perseus/` and as a standalone binary in production
let (html_shell_path, static_dir_path) = if is_standalone {
("./index.html", "./static")
let static_dir_path = if is_standalone {
"./static"
} else {
("../index.html", "../static")
"../static"
};

let immutable_store = get_immutable_store(&plugins);
let locales = get_locales(&plugins);
let app_root = get_app_root(&plugins);
let static_aliases = get_static_aliases(&plugins);
let templates_map = get_templates_map_atomic(&plugins);
let error_pages = get_error_pages(&plugins);
let immutable_store = app.get_immutable_store();
let locales = app.get_locales();
let app_root = app.get_root();
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());
// Generate the global state
let global_state_creator = get_global_state_creator();
let global_state_creator = app.get_global_state_creator();

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)
index: html_shell_path.to_string(), // The user must define their own `index.html` file
html_shell: index_view,
js_bundle: "dist/pkg/perseus_engine.js".to_string(),
// Our crate has the same name, so this will be predictable
wasm_bundle: "dist/pkg/perseus_engine_bg.wasm".to_string(),
Expand All @@ -138,8 +136,8 @@ fn get_props(is_standalone: bool) -> ServerProps<impl MutableStore, impl Transla
ServerProps {
opts,
immutable_store,
mutable_store: get_mutable_store(),
translations_manager: block_on(get_translations_manager()),
mutable_store: app.get_mutable_store(),
translations_manager: block_on(app.get_translations_manager()),
global_state_creator,
}
}
Loading