Skip to content

Commit 6b538d3

Browse files
committed
fix: fixed actix web integration
1 parent 3fd6834 commit 6b538d3

File tree

10 files changed

+23
-21
lines changed

10 files changed

+23
-21
lines changed

packages/perseus-actix-web/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@ futures = "0.3"
2828
sycamore = { version = "=0.8.0-beta.7", features = ["ssr"] }
2929

3030
[features]
31+
default = [ "dflt-server" ]
3132
# Enables the default server configuration, which provides a convenience function if you're not adding any extra routes
3233
dflt-server = [ "perseus/builder" ]

packages/perseus-actix-web/src/configurer.rs

-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ pub async fn configurer<M: MutableStore + 'static, T: TranslationsManager + 'sta
4545
global_state_creator,
4646
}: ServerProps<M, T>,
4747
) -> impl FnOnce(&mut actix_web::web::ServiceConfig) {
48-
let opts = Rc::new(opts); // TODO Find a more efficient way of doing this
4948
let render_cfg = get_render_cfg(&immutable_store)
5049
.await
5150
.expect("Couldn't get render configuration!");

packages/perseus-actix-web/src/dflt_server.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use actix_web::{App, HttpServer};
33
use futures::executor::block_on;
44
use perseus::{
55
internal::i18n::TranslationsManager, internal::serve::ServerProps, stores::MutableStore,
6-
PerseusAppBase, SsrNode,
76
};
87

98
/// 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
@@ -18,7 +17,7 @@ pub async fn dflt_server<M: MutableStore + 'static, T: TranslationsManager + 'st
1817
.configure(
1918
block_on(
2019
configurer(
21-
props
20+
props.clone()
2221
)
2322
)
2423
)

packages/perseus-actix-web/src/initial_load.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fn return_error_page(
3939
#[allow(clippy::too_many_arguments)]
4040
pub async fn initial_load<M: MutableStore, T: TranslationsManager>(
4141
req: HttpRequest,
42-
opts: web::Data<Rc<ServerOptions>>,
42+
opts: web::Data<ServerOptions>,
4343
html_shell: web::Data<HtmlShell>,
4444
render_cfg: web::Data<HashMap<String, String>>,
4545
immutable_store: web::Data<ImmutableStore>,

packages/perseus-actix-web/src/page_data.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use perseus::{
1010
stores::{ImmutableStore, MutableStore},
1111
};
1212
use serde::Deserialize;
13-
use std::rc::Rc;
1413

1514
#[derive(Deserialize)]
1615
pub struct PageDataReq {
@@ -22,7 +21,7 @@ pub struct PageDataReq {
2221
#[allow(clippy::too_many_arguments)]
2322
pub async fn page_data<M: MutableStore, T: TranslationsManager>(
2423
req: HttpRequest,
25-
opts: web::Data<Rc<ServerOptions>>,
24+
opts: web::Data<ServerOptions>,
2625
immutable_store: web::Data<ImmutableStore>,
2726
mutable_store: web::Data<M>,
2827
translations_manager: web::Data<T>,

packages/perseus-actix-web/src/translations.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ use actix_web::{web, HttpRequest, HttpResponse};
22
use fmterr::fmt_err;
33
use perseus::internal::i18n::TranslationsManager;
44
use perseus::internal::serve::ServerOptions;
5-
use std::rc::Rc;
65

76
/// The handler for calls to `.perseus/translations/{locale}`. This will manage returning errors and the like. THe JSON body returned
87
/// from this does NOT include the `locale` key, just a `HashMap<String, String>` of the translations themselves.
98
pub async fn translations<T: TranslationsManager>(
109
req: HttpRequest,
11-
opts: web::Data<Rc<ServerOptions>>,
10+
opts: web::Data<ServerOptions>,
1211
translations_manager: web::Data<T>,
1312
) -> HttpResponse {
1413
let locale = req.match_info().query("locale");

packages/perseus/src/engine/serve.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::PerseusAppBase;
66
use futures::executor::block_on;
77
use std::env;
88
use std::fs;
9+
use std::sync::Arc;
910
use sycamore::web::SsrNode;
1011

1112
// TODO Can we unify the two modes of server execution now?
@@ -67,7 +68,7 @@ pub fn get_props<M: MutableStore, T: TranslationsManager>(
6768
locales: app.get_locales(),
6869
root_id: app_root,
6970
snippets: "dist/pkg/snippets".to_string(),
70-
error_pages: app.get_error_pages(),
71+
error_pages: Arc::new(app.get_error_pages()),
7172
// This will be available directly at `/.perseus/static`
7273
static_dir: if fs::metadata(&static_dir_path).is_ok() {
7374
Some(static_dir_path)

packages/perseus/src/init.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ use futures::Future;
1616
use std::marker::PhantomData;
1717
#[cfg(not(target_arch = "wasm32"))]
1818
use std::pin::Pin;
19+
#[cfg(not(target_arch = "wasm32"))]
20+
use std::sync::Arc;
1921
use std::{collections::HashMap, rc::Rc};
2022
use sycamore::prelude::Scope;
2123
use sycamore::{
@@ -97,8 +99,9 @@ pub struct PerseusAppBase<G: Html, M: MutableStore, T: TranslationsManager> {
9799
/// The app's error pages.
98100
error_pages: ErrorPagesGetter<G>,
99101
/// The global state creator for the app.
102+
// This is wrapped in an `Arc` so we can pass it around on the engine-side (which is solely for Actix's benefit...)
100103
#[cfg(not(target_arch = "wasm32"))]
101-
global_state_creator: GlobalStateCreator,
104+
global_state_creator: Arc<GlobalStateCreator>,
102105
/// The internationalization information for the app.
103106
locales: Locales,
104107
/// The static aliases the app serves.
@@ -221,7 +224,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
221224
// We do offer default error pages, but they'll panic if they're called for production building
222225
error_pages: ErrorPagesGetter(Box::new(ErrorPages::default)),
223226
#[cfg(not(target_arch = "wasm32"))]
224-
global_state_creator: GlobalStateCreator::default(),
227+
global_state_creator: Arc::new(GlobalStateCreator::default()),
225228
// By default, we'll disable i18n (as much as I may want more websites to support more languages...)
226229
locales: Locales {
227230
default: "xx-XX".to_string(),
@@ -307,7 +310,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
307310
pub fn global_state_creator(mut self, val: GlobalStateCreator) -> Self {
308311
#[cfg(not(target_arch = "wasm32"))]
309312
{
310-
self.global_state_creator = val;
313+
self.global_state_creator = Arc::new(val);
311314
}
312315
self
313316
}
@@ -623,7 +626,7 @@ impl<G: Html, M: MutableStore, T: TranslationsManager> PerseusAppBase<G, M, T> {
623626
}
624627
/// Gets the global state creator. This can't be directly modified by plugins because of reactive type complexities.
625628
#[cfg(not(target_arch = "wasm32"))]
626-
pub fn get_global_state_creator(&self) -> GlobalStateCreator {
629+
pub fn get_global_state_creator(&self) -> Arc<GlobalStateCreator> {
627630
self.global_state_creator.clone()
628631
}
629632
/// Gets the locales information.

packages/perseus/src/server/options.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ use crate::stores::{ImmutableStore, MutableStore};
66
use crate::template::ArcTemplateMap;
77
use crate::SsrNode;
88
use std::collections::HashMap;
9+
use std::sync::Arc;
910

1011
use super::HtmlShell;
1112

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

4344
/// The full set of properties that all server integrations take.
44-
#[derive(Debug)]
45+
#[derive(Debug, Clone)]
4546
pub struct ServerProps<M: MutableStore, T: TranslationsManager> {
4647
/// The options for setting up the server.
4748
pub opts: ServerOptions,
@@ -52,5 +53,5 @@ pub struct ServerProps<M: MutableStore, T: TranslationsManager> {
5253
/// A translations manager to use.
5354
pub translations_manager: T,
5455
/// The global state creator. This is used to avoid issues with `async` and cloning in Actix Web.
55-
pub global_state_creator: GlobalStateCreator,
56+
pub global_state_creator: Arc<GlobalStateCreator>,
5657
}

packages/perseus/src/state/global_state.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ use std::rc::Rc;
99

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

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

0 commit comments

Comments
 (0)