Skip to content

Commit

Permalink
fix: fixed actix web integration
Browse files Browse the repository at this point in the history
  • Loading branch information
arctic-hen7 committed Jul 4, 2022
1 parent 3fd6834 commit 6b538d3
Show file tree
Hide file tree
Showing 10 changed files with 23 additions and 21 deletions.
1 change: 1 addition & 0 deletions packages/perseus-actix-web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ futures = "0.3"
sycamore = { version = "=0.8.0-beta.7", features = ["ssr"] }

[features]
default = [ "dflt-server" ]
# Enables the default server configuration, which provides a convenience function if you're not adding any extra routes
dflt-server = [ "perseus/builder" ]
1 change: 0 additions & 1 deletion packages/perseus-actix-web/src/configurer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ pub async fn configurer<M: MutableStore + 'static, T: TranslationsManager + 'sta
global_state_creator,
}: ServerProps<M, T>,
) -> impl FnOnce(&mut actix_web::web::ServiceConfig) {
let opts = Rc::new(opts); // TODO Find a more efficient way of doing this
let render_cfg = get_render_cfg(&immutable_store)
.await
.expect("Couldn't get render configuration!");
Expand Down
3 changes: 1 addition & 2 deletions packages/perseus-actix-web/src/dflt_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use actix_web::{App, HttpServer};
use futures::executor::block_on;
use perseus::{
internal::i18n::TranslationsManager, internal::serve::ServerProps, stores::MutableStore,
PerseusAppBase, SsrNode,
};

/// Creates and starts the default Perseus server using Actix Web. This should be run in a `main()` function annotated with `#[tokio::main]` (which requires the `macros` and
Expand All @@ -18,7 +17,7 @@ pub async fn dflt_server<M: MutableStore + 'static, T: TranslationsManager + 'st
.configure(
block_on(
configurer(
props
props.clone()
)
)
)
Expand Down
2 changes: 1 addition & 1 deletion packages/perseus-actix-web/src/initial_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ fn return_error_page(
#[allow(clippy::too_many_arguments)]
pub async fn initial_load<M: MutableStore, T: TranslationsManager>(
req: HttpRequest,
opts: web::Data<Rc<ServerOptions>>,
opts: web::Data<ServerOptions>,
html_shell: web::Data<HtmlShell>,
render_cfg: web::Data<HashMap<String, String>>,
immutable_store: web::Data<ImmutableStore>,
Expand Down
3 changes: 1 addition & 2 deletions packages/perseus-actix-web/src/page_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use perseus::{
stores::{ImmutableStore, MutableStore},
};
use serde::Deserialize;
use std::rc::Rc;

#[derive(Deserialize)]
pub struct PageDataReq {
Expand All @@ -22,7 +21,7 @@ pub struct PageDataReq {
#[allow(clippy::too_many_arguments)]
pub async fn page_data<M: MutableStore, T: TranslationsManager>(
req: HttpRequest,
opts: web::Data<Rc<ServerOptions>>,
opts: web::Data<ServerOptions>,
immutable_store: web::Data<ImmutableStore>,
mutable_store: web::Data<M>,
translations_manager: web::Data<T>,
Expand Down
3 changes: 1 addition & 2 deletions packages/perseus-actix-web/src/translations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ use actix_web::{web, HttpRequest, HttpResponse};
use fmterr::fmt_err;
use perseus::internal::i18n::TranslationsManager;
use perseus::internal::serve::ServerOptions;
use std::rc::Rc;

/// The handler for calls to `.perseus/translations/{locale}`. This will manage returning errors and the like. THe JSON body returned
/// from this does NOT include the `locale` key, just a `HashMap<String, String>` of the translations themselves.
pub async fn translations<T: TranslationsManager>(
req: HttpRequest,
opts: web::Data<Rc<ServerOptions>>,
opts: web::Data<ServerOptions>,
translations_manager: web::Data<T>,
) -> HttpResponse {
let locale = req.match_info().query("locale");
Expand Down
3 changes: 2 additions & 1 deletion packages/perseus/src/engine/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::PerseusAppBase;
use futures::executor::block_on;
use std::env;
use std::fs;
use std::sync::Arc;
use sycamore::web::SsrNode;

// TODO Can we unify the two modes of server execution now?
Expand Down Expand Up @@ -67,7 +68,7 @@ pub fn get_props<M: MutableStore, T: TranslationsManager>(
locales: app.get_locales(),
root_id: app_root,
snippets: "dist/pkg/snippets".to_string(),
error_pages: app.get_error_pages(),
error_pages: Arc::new(app.get_error_pages()),
// This will be available directly at `/.perseus/static`
static_dir: if fs::metadata(&static_dir_path).is_ok() {
Some(static_dir_path)
Expand Down
11 changes: 7 additions & 4 deletions packages/perseus/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use futures::Future;
use std::marker::PhantomData;
#[cfg(not(target_arch = "wasm32"))]
use std::pin::Pin;
#[cfg(not(target_arch = "wasm32"))]
use std::sync::Arc;
use std::{collections::HashMap, rc::Rc};
use sycamore::prelude::Scope;
use sycamore::{
Expand Down Expand Up @@ -97,8 +99,9 @@ pub struct PerseusAppBase<G: Html, M: MutableStore, T: TranslationsManager> {
/// The app's error pages.
error_pages: ErrorPagesGetter<G>,
/// The global state creator for the app.
// This is wrapped in an `Arc` so we can pass it around on the engine-side (which is solely for Actix's benefit...)
#[cfg(not(target_arch = "wasm32"))]
global_state_creator: GlobalStateCreator,
global_state_creator: Arc<GlobalStateCreator>,
/// The internationalization information for the app.
locales: Locales,
/// The static aliases the app serves.
Expand Down Expand Up @@ -221,7 +224,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
// We do offer default error pages, but they'll panic if they're called for production building
error_pages: ErrorPagesGetter(Box::new(ErrorPages::default)),
#[cfg(not(target_arch = "wasm32"))]
global_state_creator: GlobalStateCreator::default(),
global_state_creator: Arc::new(GlobalStateCreator::default()),
// By default, we'll disable i18n (as much as I may want more websites to support more languages...)
locales: Locales {
default: "xx-XX".to_string(),
Expand Down Expand Up @@ -307,7 +310,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
pub fn global_state_creator(mut self, val: GlobalStateCreator) -> Self {
#[cfg(not(target_arch = "wasm32"))]
{
self.global_state_creator = val;
self.global_state_creator = Arc::new(val);
}
self
}
Expand Down Expand Up @@ -623,7 +626,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
}
/// Gets the global state creator. This can't be directly modified by plugins because of reactive type complexities.
#[cfg(not(target_arch = "wasm32"))]
pub fn get_global_state_creator(&self) -> GlobalStateCreator {
pub fn get_global_state_creator(&self) -> Arc<GlobalStateCreator> {
self.global_state_creator.clone()
}
/// Gets the locales information.
Expand Down
11 changes: 6 additions & 5 deletions packages/perseus/src/server/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ use crate::stores::{ImmutableStore, MutableStore};
use crate::template::ArcTemplateMap;
use crate::SsrNode;
use std::collections::HashMap;
use std::sync::Arc;

use super::HtmlShell;

/// The options for setting up all server integrations. This should be literally constructed, as nothing is optional. If integrations need further properties,
/// they should expose their own options in addition to these. These should be accessed through an `Arc`/`Rc` for integration developers.
#[derive(Debug)]
/// they should expose their own options in addition to these.
#[derive(Debug, Clone)]
pub struct ServerOptions {
/// The location on the filesystem of your JavaScript bundle.
pub js_bundle: String,
Expand All @@ -32,7 +33,7 @@ pub struct ServerOptions {
/// The location of the JS interop snippets to be served as static files.
pub snippets: String,
/// The error pages for the app. These will be server-rendered if an initial load fails.
pub error_pages: ErrorPages<SsrNode>,
pub error_pages: Arc<ErrorPages<SsrNode>>,
/// The directory to serve static content from, which will be mapped to `/.perseus/static`in the browser.
pub static_dir: Option<String>,
/// A map of URLs to act as aliases for certain static resources. These are particularly designed for things like a site manifest or
Expand All @@ -41,7 +42,7 @@ pub struct ServerOptions {
}

/// The full set of properties that all server integrations take.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ServerProps<M: MutableStore, T: TranslationsManager> {
/// The options for setting up the server.
pub opts: ServerOptions,
Expand All @@ -52,5 +53,5 @@ pub struct ServerProps<M: MutableStore, T: TranslationsManager> {
/// A translations manager to use.
pub translations_manager: T,
/// The global state creator. This is used to avoid issues with `async` and cloning in Actix Web.
pub global_state_creator: GlobalStateCreator,
pub global_state_creator: Arc<GlobalStateCreator>,
}
6 changes: 3 additions & 3 deletions packages/perseus/src/state/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use std::rc::Rc;

make_async_trait!(GlobalStateCreatorFnType, RenderFnResult<String>);
/// The type of functions that generate global state. These will generate a `String` for their custom global state type.
pub type GlobalStateCreatorFn = Rc<dyn GlobalStateCreatorFnType + Send + Sync>;
pub type GlobalStateCreatorFn = Box<dyn GlobalStateCreatorFnType + Send + Sync>;

/// A creator for global state. This stores user-provided functions that will be invoked to generate global state on the client
/// and the server.
///
/// The primary purpose of this is to allow the generation of top-level app state on the server and the client. Notably,
/// this can also be interacted with by plugins.
#[derive(Default, Clone)]
#[derive(Default)]
pub struct GlobalStateCreator {
/// The function that creates state at build-time. This is roughly equivalent to the *build state* strategy for templates.
#[cfg(not(target_arch = "wasm32"))]
Expand All @@ -38,7 +38,7 @@ impl GlobalStateCreator {
mut self,
val: impl GlobalStateCreatorFnType + Send + Sync + 'static,
) -> Self {
self.build = Some(Rc::new(val));
self.build = Some(Box::new(val));
self
}
/// Adds a function to generate global state at build-time.
Expand Down

0 comments on commit 6b538d3

Please sign in to comment.