From f6568e9ce11be97390982c69dedcd737b5692eac Mon Sep 17 00:00:00 2001 From: arctic-hen7 Date: Sun, 1 Jan 2023 11:06:11 +1100 Subject: [PATCH] feat: added support for wasm engines BREAKING CHANGE: all target-gates should switch to `#[cfg(engine)]` and `#[cfg(client)]`, rather than using `target_arch` BREAKING CHANGE: removed nnow obsolete `#[perseus::engine]` and `#[perseus::browser]` macros --- examples/.base/Cargo.toml | 6 +- examples/comprehensive/tiny/Cargo.toml | 4 +- .../comprehensive/tiny/Cargo.toml.example | 4 +- examples/core/basic/Cargo.toml | 6 +- examples/core/basic/Cargo.toml.example | 4 +- examples/core/capsules/Cargo.toml | 6 +- examples/core/custom_server/Cargo.toml | 6 +- examples/core/custom_server/src/main.rs | 4 +- examples/core/error_views/Cargo.toml | 6 +- .../core/error_views/src/templates/index.rs | 2 +- examples/core/freezing_and_thawing/Cargo.toml | 4 +- .../src/templates/about.rs | 2 +- .../src/templates/index.rs | 4 +- examples/core/global_state/Cargo.toml | 4 +- examples/core/helper_build_state/Cargo.toml | 6 +- examples/core/i18n/Cargo.toml | 4 +- examples/core/idb_freezing/Cargo.toml | 4 +- .../core/idb_freezing/src/templates/about.rs | 2 +- .../core/idb_freezing/src/templates/index.rs | 4 +- examples/core/index_view/Cargo.toml | 4 +- examples/core/js_interop/Cargo.toml | 6 +- .../core/js_interop/src/templates/index.rs | 6 +- examples/core/plugins/Cargo.toml | 4 +- examples/core/preload/Cargo.toml | 6 +- examples/core/preload/src/templates/index.rs | 2 +- examples/core/router_state/Cargo.toml | 4 +- .../core/router_state/src/templates/index.rs | 2 +- examples/core/rx_state/Cargo.toml | 4 +- examples/core/set_headers/Cargo.toml | 4 +- examples/core/state_generation/Cargo.toml | 4 +- examples/core/static_content/Cargo.toml | 4 +- examples/core/suspense/Cargo.toml | 6 +- examples/core/suspense/src/templates/index.rs | 4 +- examples/core/unreactive/Cargo.toml | 4 +- examples/demos/auth/Cargo.toml | 4 +- examples/demos/auth/src/global_state.rs | 13 +- examples/demos/auth/src/templates/index.rs | 6 +- examples/demos/fetching/Cargo.toml | 4 +- .../demos/fetching/src/templates/index.rs | 4 +- examples/demos/full_page_layout/Cargo.toml | 6 +- examples/website/app_in_a_file/Cargo.toml | 4 +- examples/website/i18n/Cargo.toml | 4 +- examples/website/state_generation/Cargo.toml | 4 +- packages/perseus-actix-web/src/lib.rs | 1 + packages/perseus-axum/src/lib.rs | 1 + packages/perseus-cli/src/build.rs | 43 +++--- packages/perseus-cli/src/check.rs | 11 +- packages/perseus-cli/src/export.rs | 11 +- packages/perseus-cli/src/init.rs | 4 +- packages/perseus-cli/src/parse.rs | 3 +- packages/perseus-cli/src/serve.rs | 5 +- packages/perseus-cli/src/tinker.rs | 3 +- packages/perseus-integration/src/lib.rs | 2 + packages/perseus-macro/src/entrypoint.rs | 12 +- packages/perseus-macro/src/lib.rs | 35 +---- packages/perseus-macro/src/rx_state.rs | 2 +- packages/perseus-warp/src/lib.rs | 1 + packages/perseus/Cargo.toml | 4 +- packages/perseus/src/error_views.rs | 18 +-- packages/perseus/src/errors.rs | 26 ++-- packages/perseus/src/i18n/mod.rs | 8 +- .../perseus/src/i18n/translations_manager.rs | 38 ++--- packages/perseus/src/init.rs | 130 +++++++++--------- packages/perseus/src/lib.rs | 41 +++--- packages/perseus/src/plugins/functional.rs | 16 +-- packages/perseus/src/plugins/plugins_list.rs | 10 +- packages/perseus/src/reactor/error.rs | 2 +- packages/perseus/src/reactor/global_state.rs | 10 +- packages/perseus/src/reactor/mod.rs | 70 +++++----- packages/perseus/src/reactor/render_mode.rs | 2 +- packages/perseus/src/reactor/state.rs | 18 +-- packages/perseus/src/reactor/widget_state.rs | 30 ++-- packages/perseus/src/router/mod.rs | 12 +- packages/perseus/src/state/global_state.rs | 68 ++++----- packages/perseus/src/state/mod.rs | 20 +-- .../src/state/rx_collections/rx_hash_map.rs | 4 +- .../rx_collections/rx_hash_map_nested.rs | 4 +- .../src/state/rx_collections/rx_vec.rs | 4 +- .../src/state/rx_collections/rx_vec_nested.rs | 4 +- packages/perseus/src/state/rx_result.rs | 4 +- packages/perseus/src/state/rx_state.rs | 6 +- .../perseus/src/state/state_generator_info.rs | 2 +- packages/perseus/src/state/state_store.rs | 12 +- packages/perseus/src/stores/immutable.rs | 14 +- packages/perseus/src/stores/mutable.rs | 16 +-- packages/perseus/src/template/capsule.rs | 28 ++-- packages/perseus/src/template/core/getters.rs | 22 +-- packages/perseus/src/template/core/mod.rs | 44 +++--- .../perseus/src/template/core/renderers.rs | 36 ++--- packages/perseus/src/template/core/setters.rs | 48 +++---- .../src/template/core/state_setters.rs | 18 +-- packages/perseus/src/template/core/utils.rs | 4 +- packages/perseus/src/template/mod.rs | 12 +- packages/perseus/src/template/render_ctx.rs | 34 ++--- .../perseus/src/template/widget_component.rs | 10 +- packages/perseus/src/utils/decode_time_str.rs | 8 +- packages/perseus/src/utils/log.rs | 4 +- packages/perseus/src/utils/mod.rs | 28 ++-- packages/perseus/src/utils/path_prefix.rs | 4 +- packages/perseus/src/utils/render.rs | 10 +- 100 files changed, 611 insertions(+), 621 deletions(-) diff --git a/examples/.base/Cargo.toml b/examples/.base/Cargo.toml index d69e19973e..10e5453401 100644 --- a/examples/.base/Cargo.toml +++ b/examples/.base/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/comprehensive/tiny/Cargo.toml b/examples/comprehensive/tiny/Cargo.toml index 907fd51d1d..ab57a266ca 100644 --- a/examples/comprehensive/tiny/Cargo.toml +++ b/examples/comprehensive/tiny/Cargo.toml @@ -9,11 +9,11 @@ edition = "2021" perseus = { path = "../../../packages/perseus" } sycamore = "^0.8.1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/comprehensive/tiny/Cargo.toml.example b/examples/comprehensive/tiny/Cargo.toml.example index eeb00a101b..ccaaf11e0f 100644 --- a/examples/comprehensive/tiny/Cargo.toml.example +++ b/examples/comprehensive/tiny/Cargo.toml.example @@ -7,8 +7,8 @@ edition = "2021" perseus = { version = "=0.4.0-beta.11", features = [ "hydrate" ] } sycamore = "^0.8.1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { version = "=0.4.0-beta.11", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/basic/Cargo.toml b/examples/core/basic/Cargo.toml index 21758c22dd..81e2b103c4 100644 --- a/examples/core/basic/Cargo.toml +++ b/examples/core/basic/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/basic/Cargo.toml.example b/examples/core/basic/Cargo.toml.example index adde051c83..68a4a4b826 100644 --- a/examples/core/basic/Cargo.toml.example +++ b/examples/core/basic/Cargo.toml.example @@ -11,8 +11,8 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { version = "=0.4.0-beta.11", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/capsules/Cargo.toml b/examples/core/capsules/Cargo.toml index 1a0ca1c43c..5ee33a59b9 100644 --- a/examples/core/capsules/Cargo.toml +++ b/examples/core/capsules/Cargo.toml @@ -12,14 +12,14 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" lazy_static = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/custom_server/Cargo.toml b/examples/core/custom_server/Cargo.toml index 35c91300f8..4925a7d8b9 100644 --- a/examples/core/custom_server/Cargo.toml +++ b/examples/core/custom_server/Cargo.toml @@ -11,12 +11,12 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } warp = { package = "warp-fix-171", version = "0.3" } # Temporary until Warp #171 is resolved -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/custom_server/src/main.rs b/examples/core/custom_server/src/main.rs index 873e0024cb..d0438ec005 100644 --- a/examples/core/custom_server/src/main.rs +++ b/examples/core/custom_server/src/main.rs @@ -4,8 +4,8 @@ use perseus::prelude::*; // Note: we use fully-qualified paths in the types to this function so we don't // have to target-gate some more imports -#[cfg(not(target_arch = "wasm32"))] // We only have access to `warp` etc. on the engine-side, so this function - // should only exist there +#[cfg(engine)] // We only have access to `warp` etc. on the engine-side, so this function + // should only exist there pub async fn dflt_server< M: perseus::stores::MutableStore + 'static, T: perseus::i18n::TranslationsManager + 'static, diff --git a/examples/core/error_views/Cargo.toml b/examples/core/error_views/Cargo.toml index d69e19973e..10e5453401 100644 --- a/examples/core/error_views/Cargo.toml +++ b/examples/core/error_views/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/error_views/src/templates/index.rs b/examples/core/error_views/src/templates/index.rs index 10c9bd6076..9d79a79bcf 100644 --- a/examples/core/error_views/src/templates/index.rs +++ b/examples/core/error_views/src/templates/index.rs @@ -4,7 +4,7 @@ use sycamore::prelude::*; fn index_page(cx: Scope) -> View { // Deliberate panic to show how panic handling works (in an `on_mount` so we // still reach the right checkpoints for testing) - #[cfg(target_arch = "wasm32")] + #[cfg(client)] on_mount(cx, || { panic!(); }); diff --git a/examples/core/freezing_and_thawing/Cargo.toml b/examples/core/freezing_and_thawing/Cargo.toml index ea57f0c6b1..461dbb9785 100644 --- a/examples/core/freezing_and_thawing/Cargo.toml +++ b/examples/core/freezing_and_thawing/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/freezing_and_thawing/src/templates/about.rs b/examples/core/freezing_and_thawing/src/templates/about.rs index 95dc7ce29b..f4b1c84d5c 100644 --- a/examples/core/freezing_and_thawing/src/templates/about.rs +++ b/examples/core/freezing_and_thawing/src/templates/about.rs @@ -20,7 +20,7 @@ fn about_page(cx: Scope) -> View { // We'll let the user freeze from here to demonstrate that the frozen state also navigates back to the last route button(id = "freeze_button", on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { use perseus::state::Freeze; frozen_app.set(render_ctx.freeze()); diff --git a/examples/core/freezing_and_thawing/src/templates/index.rs b/examples/core/freezing_and_thawing/src/templates/index.rs index 035bd851ae..bd3a573ae8 100644 --- a/examples/core/freezing_and_thawing/src/templates/index.rs +++ b/examples/core/freezing_and_thawing/src/templates/index.rs @@ -29,7 +29,7 @@ fn index_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a IndexPageStateRx br() button(id = "freeze_button", on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { use perseus::state::Freeze; frozen_app.set(reactor.freeze()); @@ -39,7 +39,7 @@ fn index_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a IndexPageStateRx input(id = "thaw_input", bind:value = frozen_app, placeholder = "Frozen state") button(id = "thaw_button", on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] reactor.thaw(&frozen_app.get(), perseus::state::ThawPrefs { page: perseus::state::PageThawPrefs::IncludeAll, global_prefer_frozen: true diff --git a/examples/core/global_state/Cargo.toml b/examples/core/global_state/Cargo.toml index f97826b49a..3a5897ac14 100644 --- a/examples/core/global_state/Cargo.toml +++ b/examples/core/global_state/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/helper_build_state/Cargo.toml b/examples/core/helper_build_state/Cargo.toml index 86307ca6f0..cd156f37f4 100644 --- a/examples/core/helper_build_state/Cargo.toml +++ b/examples/core/helper_build_state/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/i18n/Cargo.toml b/examples/core/i18n/Cargo.toml index 8b40a80c19..e90c26ccc4 100644 --- a/examples/core/i18n/Cargo.toml +++ b/examples/core/i18n/Cargo.toml @@ -17,11 +17,11 @@ urlencoding = "2.1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/idb_freezing/Cargo.toml b/examples/core/idb_freezing/Cargo.toml index 52080aed76..6e254a6025 100644 --- a/examples/core/idb_freezing/Cargo.toml +++ b/examples/core/idb_freezing/Cargo.toml @@ -15,11 +15,11 @@ wasm-bindgen-futures = "0.4" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/idb_freezing/src/templates/about.rs b/examples/core/idb_freezing/src/templates/about.rs index a2a373d8bc..2bfc62130a 100644 --- a/examples/core/idb_freezing/src/templates/about.rs +++ b/examples/core/idb_freezing/src/templates/about.rs @@ -22,7 +22,7 @@ fn about_page(cx: Scope) -> View { // We'll let the user freeze from here to demonstrate that the frozen state also navigates back to the last route button(id = "freeze_button", on:click = move |_| { // The IndexedDB API is asynchronous, so we'll spawn a future - #[cfg(target_arch = "wasm32")] + #[cfg(client)] spawn_local_scoped(cx, async move { use perseus::state::{IdbFrozenStateStore, Freeze}; // We do this here (rather than when we get the render context) so that it's updated whenever we press the button diff --git a/examples/core/idb_freezing/src/templates/index.rs b/examples/core/idb_freezing/src/templates/index.rs index 8740a4d855..cf0ee5a593 100644 --- a/examples/core/idb_freezing/src/templates/index.rs +++ b/examples/core/idb_freezing/src/templates/index.rs @@ -32,7 +32,7 @@ fn index_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a IndexPropsRx) -> button(id = "freeze_button", on:click = move |_| { // The IndexedDB API is asynchronous, so we'll spawn a future - #[cfg(target_arch = "wasm32")] // The freezing types are only available in the browser + #[cfg(client)] // The freezing types are only available in the browser spawn_local_scoped(cx, async { use perseus::state::{IdbFrozenStateStore, Freeze, PageThawPrefs, ThawPrefs}; // We do this here (rather than when we get the reactor) so that it's updated whenever we press the button @@ -54,7 +54,7 @@ fn index_page<'a, G: Html>(cx: BoundedScope<'_, 'a>, state: &'a IndexPropsRx) -> button(id = "thaw_button", on:click = move |_| { // The IndexedDB API is asynchronous, so we'll spawn a future - #[cfg(target_arch = "wasm32")] // The freezing types are only available in the browser + #[cfg(client)] // The freezing types are only available in the browser spawn_local_scoped(cx, async move { use perseus::state::{IdbFrozenStateStore, Freeze, PageThawPrefs, ThawPrefs}; let idb_store = match IdbFrozenStateStore::new().await { diff --git a/examples/core/index_view/Cargo.toml b/examples/core/index_view/Cargo.toml index 103b316314..5b862afb39 100644 --- a/examples/core/index_view/Cargo.toml +++ b/examples/core/index_view/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/js_interop/Cargo.toml b/examples/core/js_interop/Cargo.toml index a64fd5babf..6d5d730520 100644 --- a/examples/core/js_interop/Cargo.toml +++ b/examples/core/js_interop/Cargo.toml @@ -11,15 +11,15 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] wasm-bindgen = "0.2" diff --git a/examples/core/js_interop/src/templates/index.rs b/examples/core/js_interop/src/templates/index.rs index 9059fe252d..b95d2565b7 100644 --- a/examples/core/js_interop/src/templates/index.rs +++ b/examples/core/js_interop/src/templates/index.rs @@ -1,6 +1,6 @@ use perseus::prelude::*; use sycamore::prelude::*; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use wasm_bindgen::prelude::wasm_bindgen; fn index_page(cx: Scope) -> View { @@ -8,7 +8,7 @@ fn index_page(cx: Scope) -> View { // We'll use JS to change this message manually p(id = "message") { "Hello World!" } button(id = "change-message", on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] change_message() }) { "Change message with JS" } } @@ -19,7 +19,7 @@ pub fn get_template() -> Template { } // Of course, JS will only run in the browser, so this should be browser-only -#[cfg(target_arch = "wasm32")] +#[cfg(client)] // This path should be relative to the root of your project // That file will then be hosted behind `/.perseus/` and automatically fetched as needed #[wasm_bindgen(module = "/src/changeMessage.js")] diff --git a/examples/core/plugins/Cargo.toml b/examples/core/plugins/Cargo.toml index b849f1687d..fe2ab1886d 100644 --- a/examples/core/plugins/Cargo.toml +++ b/examples/core/plugins/Cargo.toml @@ -15,11 +15,11 @@ toml = "0.5" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/preload/Cargo.toml b/examples/core/preload/Cargo.toml index fdd8961270..edf761a1ef 100644 --- a/examples/core/preload/Cargo.toml +++ b/examples/core/preload/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/preload/src/templates/index.rs b/examples/core/preload/src/templates/index.rs index 5296ac0b22..f50ae1e617 100644 --- a/examples/core/preload/src/templates/index.rs +++ b/examples/core/preload/src/templates/index.rs @@ -3,7 +3,7 @@ use sycamore::prelude::*; fn index_page(cx: Scope) -> View { // We can't preload pages on the engine-side - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { // Get the reactor first, which is the one-stop-shop for everything // internal to Perseus in the browser diff --git a/examples/core/router_state/Cargo.toml b/examples/core/router_state/Cargo.toml index beb470b1a4..280805648f 100644 --- a/examples/core/router_state/Cargo.toml +++ b/examples/core/router_state/Cargo.toml @@ -11,11 +11,11 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/router_state/src/templates/index.rs b/examples/core/router_state/src/templates/index.rs index 06f76b938d..417577be4a 100644 --- a/examples/core/router_state/src/templates/index.rs +++ b/examples/core/router_state/src/templates/index.rs @@ -4,7 +4,7 @@ use sycamore::prelude::*; fn router_state_page(cx: Scope) -> View { let load_state_str = create_signal(cx, "We're on the server.".to_string()); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { use perseus::router::RouterLoadState; let load_state = Reactor::::from_cx(cx).router_state.get_load_state(cx); diff --git a/examples/core/rx_state/Cargo.toml b/examples/core/rx_state/Cargo.toml index 30b4627686..fa11c0cf43 100644 --- a/examples/core/rx_state/Cargo.toml +++ b/examples/core/rx_state/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/set_headers/Cargo.toml b/examples/core/set_headers/Cargo.toml index 89f9bdbe43..30488b1b4a 100644 --- a/examples/core/set_headers/Cargo.toml +++ b/examples/core/set_headers/Cargo.toml @@ -15,11 +15,11 @@ serde_json = "1" fantoccini = "0.17" ureq = "2" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/state_generation/Cargo.toml b/examples/core/state_generation/Cargo.toml index 277d60b98a..fbb12ea99c 100644 --- a/examples/core/state_generation/Cargo.toml +++ b/examples/core/state_generation/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/static_content/Cargo.toml b/examples/core/static_content/Cargo.toml index b99f8df662..8e16e17b34 100644 --- a/examples/core/static_content/Cargo.toml +++ b/examples/core/static_content/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/core/suspense/Cargo.toml b/examples/core/suspense/Cargo.toml index 44f65a5ea1..7885af13c9 100644 --- a/examples/core/suspense/Cargo.toml +++ b/examples/core/suspense/Cargo.toml @@ -11,15 +11,15 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] gloo-timers = { version = "0.2", features = [ "futures" ] } # Just for this example to show that handlers are truly async diff --git a/examples/core/suspense/src/templates/index.rs b/examples/core/suspense/src/templates/index.rs index a66765ef19..b183720de1 100644 --- a/examples/core/suspense/src/templates/index.rs +++ b/examples/core/suspense/src/templates/index.rs @@ -2,9 +2,9 @@ use perseus::prelude::*; use serde::{Deserialize, Serialize}; use sycamore::prelude::*; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use gloo_timers::future::sleep; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::time::Duration; #[derive(Serialize, Deserialize, Clone, ReactiveState)] diff --git a/examples/core/unreactive/Cargo.toml b/examples/core/unreactive/Cargo.toml index 0294c4750d..e432f53e22 100644 --- a/examples/core/unreactive/Cargo.toml +++ b/examples/core/unreactive/Cargo.toml @@ -14,11 +14,11 @@ serde_json = "1" [dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/demos/auth/Cargo.toml b/examples/demos/auth/Cargo.toml index 36869adf55..6ea91acafe 100644 --- a/examples/demos/auth/Cargo.toml +++ b/examples/demos/auth/Cargo.toml @@ -12,13 +12,13 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] # We need the `HtmlDocument` feature to be able to use cookies (which this example does) web-sys = { version = "0.3", features = [ "Storage" ] } diff --git a/examples/demos/auth/src/global_state.rs b/examples/demos/auth/src/global_state.rs index 5797af9847..cc8dc0562e 100644 --- a/examples/demos/auth/src/global_state.rs +++ b/examples/demos/auth/src/global_state.rs @@ -51,15 +51,12 @@ pub struct AuthData { // There's no point in implementing it on the unreactive version, since this // will only be called from within the browser, in which we have a reactive // version. -// -// Unfortunately, Rust doesn't let us use the reference alias for this, so -// we add `PerseusRxRef`, which is the internal name. -#[cfg(target_arch = "wasm32")] // These functions all use `web_sys`, and so won't work on the server-side -impl<'a> AuthDataPerseusRxRef<'a> { +#[cfg(client)] // These functions all use `web_sys`, and so won't work on the server-side +impl AuthDataRx { /// Checks whether or not the user is logged in and modifies the internal /// state accordingly. If this has already been run, it won't do anything /// (aka. it will only run if it's `Server`) - pub fn detect_state(&'a self) { + pub fn detect_state(&self) { // If we've checked the login status before, then we should assume the status // hasn't changed (we'd change this in a login/logout page) if let LoginState::Yes | LoginState::No = *self.state.get() { @@ -87,14 +84,14 @@ impl<'a> AuthDataPerseusRxRef<'a> { } /// Logs the user in with the given username. - pub fn login(&'a self, username: &str) { + pub fn login(&self, username: &str) { let storage = web_sys::window().unwrap().local_storage().unwrap().unwrap(); storage.set("username", username).unwrap(); self.state.set(LoginState::Yes); self.username.set(username.to_string()); } /// Logs the user out. - pub fn logout(&'a self) { + pub fn logout(&self) { let storage = web_sys::window().unwrap().local_storage().unwrap().unwrap(); storage.delete("username").unwrap(); self.state.set(LoginState::No); diff --git a/examples/demos/auth/src/templates/index.rs b/examples/demos/auth/src/templates/index.rs index fe261f1d82..50516b8240 100644 --- a/examples/demos/auth/src/templates/index.rs +++ b/examples/demos/auth/src/templates/index.rs @@ -15,7 +15,7 @@ fn index_view(cx: Scope) -> View { // on the server too) This will only cause a block on the first load, // because this function just returns straight away if the state is already // known - #[cfg(target_arch = "wasm32")] + #[cfg(client)] auth.detect_state(); view! { cx, @@ -26,7 +26,7 @@ fn index_view(cx: Scope) -> View { view! { cx, h1 { (format!("Welcome back, {}!", &username)) } button(on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] auth.logout(); }) { "Logout" } } @@ -36,7 +36,7 @@ fn index_view(cx: Scope) -> View { h1 { "Welcome, stranger!" } input(bind:value = entered_username, placeholder = "Username") button(on:click = |_| { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] auth.login(&entered_username.get()) }) { "Login" } }, diff --git a/examples/demos/fetching/Cargo.toml b/examples/demos/fetching/Cargo.toml index dd1cf9e602..12bf5aa75f 100644 --- a/examples/demos/fetching/Cargo.toml +++ b/examples/demos/fetching/Cargo.toml @@ -11,7 +11,7 @@ sycamore = "^0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) @@ -19,5 +19,5 @@ perseus-warp = { package = "perseus-integration", path = "../../../packages/pers # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } reqwest = "0.11" -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] reqwasm = "0.4" diff --git a/examples/demos/fetching/src/templates/index.rs b/examples/demos/fetching/src/templates/index.rs index 2bbfa517ee..9ca577e376 100644 --- a/examples/demos/fetching/src/templates/index.rs +++ b/examples/demos/fetching/src/templates/index.rs @@ -20,7 +20,7 @@ fn index_page<'a, G: Html>( // `reqwasm` wraps browser-specific APIs, so we don't want it running on the // server If the browser IP has already been fetched (e.g. if we've come // here for the second time in the same session), we won't bother re-fetching - #[cfg(target_arch = "wasm32")] + #[cfg(client)] // Because we only have `reqwasm` on the client-side, we make sure this is only *compiled* in // the browser as well if browser_ip.get().is_none() { @@ -30,7 +30,7 @@ fn index_page<'a, G: Html>( // // We want to access the `message` `Signal`, so we'll clone it in (and then we // need `move` because this has to be `'static`) - perseus::spawn_local_scoped(cx, async { + spawn_local_scoped(cx, async { // This interface may seem weird, that's because it wraps the browser's Fetch // API We request from a local path here because of CORS // restrictions (see the book) diff --git a/examples/demos/full_page_layout/Cargo.toml b/examples/demos/full_page_layout/Cargo.toml index 9fc8e2f370..5e23f00611 100644 --- a/examples/demos/full_page_layout/Cargo.toml +++ b/examples/demos/full_page_layout/Cargo.toml @@ -11,14 +11,14 @@ sycamore = "=0.8.1" serde = { version = "1", features = ["derive"] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +[target.'cfg(engine)'.dev-dependencies] fantoccini = "0.17" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } ## **WARNING!** Before running this example outside the Perseus repo, replace the below line with ## the one commented out below it (changing the path dependency to the version you want to use) perseus-warp = { package = "perseus-integration", path = "../../../packages/perseus-integration", default-features = false } # perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/website/app_in_a_file/Cargo.toml b/examples/website/app_in_a_file/Cargo.toml index cd4c0ea189..b0c9138104 100644 --- a/examples/website/app_in_a_file/Cargo.toml +++ b/examples/website/app_in_a_file/Cargo.toml @@ -11,8 +11,8 @@ sycamore = "^0.8.1" serde = { version = "1", features = [ "derive" ] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/website/i18n/Cargo.toml b/examples/website/i18n/Cargo.toml index 93ff022d34..dbb05440d2 100644 --- a/examples/website/i18n/Cargo.toml +++ b/examples/website/i18n/Cargo.toml @@ -11,8 +11,8 @@ sycamore = "^0.8.1" serde = { version = "1", features = [ "derive" ] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/examples/website/state_generation/Cargo.toml b/examples/website/state_generation/Cargo.toml index 34e611b5eb..dd8e1c68e3 100644 --- a/examples/website/state_generation/Cargo.toml +++ b/examples/website/state_generation/Cargo.toml @@ -11,8 +11,8 @@ sycamore = "^0.8.1" serde = { version = "1", features = [ "derive" ] } serde_json = "1" -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { path = "../../../packages/perseus-warp", features = [ "dflt-server" ] } -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] diff --git a/packages/perseus-actix-web/src/lib.rs b/packages/perseus-actix-web/src/lib.rs index 3641b04c5d..d1a148371e 100644 --- a/packages/perseus-actix-web/src/lib.rs +++ b/packages/perseus-actix-web/src/lib.rs @@ -6,6 +6,7 @@ This is the API documentation for the `perseus-actix-web` package, which allows documentation, and this should mostly be used as a secondary reference source. You can also find full usage examples [here](https://github.com/arctic-hen7/perseus/tree/main/examples). */ +#![cfg(engine)] // This crate needs to be run with the Perseus CLI #![deny(missing_docs)] #![deny(missing_debug_implementations)] diff --git a/packages/perseus-axum/src/lib.rs b/packages/perseus-axum/src/lib.rs index 26caace7a2..b2c73231b1 100644 --- a/packages/perseus-axum/src/lib.rs +++ b/packages/perseus-axum/src/lib.rs @@ -6,6 +6,7 @@ This is the API documentation for the `perseus-axum` package, which allows Perse documentation, and this should mostly be used as a secondary reference source. You can also find full usage examples [here](https://github.com/arctic-hen7/perseus/tree/main/examples). */ +#![cfg(engine)] // This crate needs to be run with the Perseus CLI #![deny(missing_docs)] #![deny(missing_debug_implementations)] diff --git a/packages/perseus-cli/src/build.rs b/packages/perseus-cli/src/build.rs index 0bd2fcf6a8..8cf7cd154b 100644 --- a/packages/perseus-cli/src/build.rs +++ b/packages/perseus-cli/src/build.rs @@ -44,13 +44,14 @@ pub fn build_internal( // We need to own this for the threads let tools = tools.clone(); let Opts { - wasm_release_rustflags, + mut wasm_release_rustflags, cargo_engine_args, cargo_browser_args, wasm_bindgen_args, wasm_opt_args, .. } = global_opts.clone(); + wasm_release_rustflags.push_str(" --cfg=client"); let crate_name = get_user_crate_name(&dir)?; // Static generation message @@ -90,7 +91,8 @@ pub fn build_internal( &sg_msg, vec![ ("PERSEUS_ENGINE_OPERATION", "build"), - ("CARGO_TARGET_DIR", "dist/target_engine") + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") ] )?); @@ -101,22 +103,22 @@ pub fn build_internal( let wb_thread = spawn_thread( move || { let mut cmds = vec![ - // Build the Wasm artifact first (and we know where it will end up, since we're setting the target directory) - format!( - "{} build --target wasm32-unknown-unknown {} {}", - tools.cargo_browser, - if is_release { "--release" } else { "" }, - cargo_browser_args - ), - // NOTE The `wasm-bindgen` version has to be *identical* to the dependency version - format!( - "{cmd} ./dist/target_wasm/wasm32-unknown-unknown/{profile}/{crate_name}.wasm --out-dir dist/pkg --out-name perseus_engine --target web {args}", - cmd=tools.wasm_bindgen, - profile={ if is_release { "release" } else { "debug" } }, - args=wasm_bindgen_args, - crate_name=crate_name - ) - ]; + // Build the Wasm artifact first (and we know where it will end up, since we're setting the target directory) + format!( + "{} build --target wasm32-unknown-unknown {} {}", + tools.cargo_browser, + if is_release { "--release" } else { "" }, + cargo_browser_args + ), + // NOTE The `wasm-bindgen` version has to be *identical* to the dependency version + format!( + "{cmd} ./dist/target_wasm/wasm32-unknown-unknown/{profile}/{crate_name}.wasm --out-dir dist/pkg --out-name perseus_engine --target web {args}", + cmd=tools.wasm_bindgen, + profile={ if is_release { "release" } else { "debug" } }, + args=wasm_bindgen_args, + crate_name=crate_name + ) + ]; // If we're building for release, then we should run `wasm-opt` if is_release { cmds.push(format!( @@ -137,7 +139,10 @@ pub fn build_internal( ("RUSTFLAGS", &wasm_release_rustflags), ] } else { - vec![("CARGO_TARGET_DIR", "dist/target_wasm")] + vec![ + ("CARGO_TARGET_DIR", "dist/target_wasm"), + ("RUSTFLAGS", "--cfg=client"), + ] } )?); diff --git a/packages/perseus-cli/src/check.rs b/packages/perseus-cli/src/check.rs index ef79e33839..e18403139c 100644 --- a/packages/perseus-cli/src/check.rs +++ b/packages/perseus-cli/src/check.rs @@ -122,7 +122,8 @@ fn cargo_check( // We still need this for checking, because otherwise we can't check the engine // and the browser simultaneously (different targets, so no // commonalities gained by one directory) - ("CARGO_TARGET_DIR", "dist/target_engine") + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") ] )?); @@ -140,7 +141,10 @@ fn cargo_check( &browser_dir, &browser_spinner, &browser_msg, - vec![("CARGO_TARGET_DIR", "dist/target_wasm"),] + vec![ + ("CARGO_TARGET_DIR", "dist/target_wasm"), + ("RUSTFLAGS", "--cfg=client") + ] )?); Ok(0) @@ -180,7 +184,8 @@ fn run_static_generation( &msg, vec![ ("PERSEUS_ENGINE_OPERATION", "build"), - ("CARGO_TARGET_DIR", "dist/target_engine") + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") ] )?); diff --git a/packages/perseus-cli/src/export.rs b/packages/perseus-cli/src/export.rs index d6d13f4dca..da8c1bc351 100644 --- a/packages/perseus-cli/src/export.rs +++ b/packages/perseus-cli/src/export.rs @@ -159,10 +159,11 @@ pub fn export_internal( cargo_engine_args, wasm_bindgen_args, wasm_opt_args, - wasm_release_rustflags, + mut wasm_release_rustflags, .. } = global_opts.clone(); let crate_name = get_user_crate_name(&dir)?; + wasm_release_rustflags.push_str(" --cfg=client"); // Exporting pages message let ep_msg = format!( @@ -201,7 +202,8 @@ pub fn export_internal( &ep_msg, vec![ ("PERSEUS_ENGINE_OPERATION", "export"), - ("CARGO_TARGET_DIR", "dist/target_engine") + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") ] )?); @@ -248,7 +250,10 @@ pub fn export_internal( ("RUSTFLAGS", &wasm_release_rustflags), ] } else { - vec![("CARGO_TARGET_DIR", "dist/target_wasm")] + vec![ + ("CARGO_TARGET_DIR", "dist/target_wasm"), + ("RUSTFLAGS", "--cfg=client"), + ] } )?); diff --git a/packages/perseus-cli/src/init.rs b/packages/perseus-cli/src/init.rs index a9d8da56b6..1af3397dd7 100644 --- a/packages/perseus-cli/src/init.rs +++ b/packages/perseus-cli/src/init.rs @@ -135,12 +135,12 @@ serde = { version = "1", features = [ "derive" ] } serde_json = "1" # Engine-only dependencies go here -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(browser)'.dependencies] tokio = { version = "1", features = [ "macros", "rt", "rt-multi-thread" ] } perseus-warp = { version = "=%perseus_version", features = [ "dflt-server" ] } # Browser-only dependencies go here -[target.'cfg(target_arch = "wasm32")'.dependencies]"#; +[target.'cfg(client)'.dependencies]"#; static DFLT_INIT_GITIGNORE: &str = r#"dist/"#; static DFLT_INIT_MAIN_RS: &str = r#"mod templates; diff --git a/packages/perseus-cli/src/parse.rs b/packages/perseus-cli/src/parse.rs index 5bac503d30..1a64588099 100644 --- a/packages/perseus-cli/src/parse.rs +++ b/packages/perseus-cli/src/parse.rs @@ -32,7 +32,8 @@ pub struct Opts { /// The path to `rustup` #[clap(long, default_value = "rustup", global = true)] pub rustup_path: String, - /// The value of `RUSTFLAGS` when building for Wasm in release mode + /// The value of `RUSTFLAGS` when building for Wasm in release mode (this + /// will not impact internal target-gating) #[clap( long, default_value = "-C opt-level=z -C codegen-units=1", diff --git a/packages/perseus-cli/src/serve.rs b/packages/perseus-cli/src/serve.rs index 456b574057..864630663f 100644 --- a/packages/perseus-cli/src/serve.rs +++ b/packages/perseus-cli/src/serve.rs @@ -83,7 +83,10 @@ fn build_server( &sb_target, &sb_spinner, &sb_msg, - vec![("CARGO_TARGET_DIR", "dist/target_engine")] + vec![ + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") + ] )?); let msgs: Vec<&str> = stdout.trim().split('\n').collect(); diff --git a/packages/perseus-cli/src/tinker.rs b/packages/perseus-cli/src/tinker.rs index d2bf403670..6a84738f74 100644 --- a/packages/perseus-cli/src/tinker.rs +++ b/packages/perseus-cli/src/tinker.rs @@ -62,7 +62,8 @@ pub fn tinker_internal( &tk_msg, vec![ ("PERSEUS_ENGINE_OPERATION", "tinker"), - ("CARGO_TARGET_DIR", "dist/target_engine") + ("CARGO_TARGET_DIR", "dist/target_engine"), + ("RUSTFLAGS", "--cfg=engine") ] )?); diff --git a/packages/perseus-integration/src/lib.rs b/packages/perseus-integration/src/lib.rs index 2c2893d479..8f67d7ef1d 100644 --- a/packages/perseus-integration/src/lib.rs +++ b/packages/perseus-integration/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg(engine)] + #[cfg(feature = "actix-web")] pub use perseus_actix_web::dflt_server; #[cfg(feature = "axum")] diff --git a/packages/perseus-macro/src/entrypoint.rs b/packages/perseus-macro/src/entrypoint.rs index d4183fad7a..3065d549e4 100644 --- a/packages/perseus-macro/src/entrypoint.rs +++ b/packages/perseus-macro/src/entrypoint.rs @@ -170,7 +170,7 @@ pub fn main_impl(input: MainFn, server_fn: Path) -> TokenStream { // engine (all based around the default engine) let output = quote! { // The engine-specific `main` function - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[tokio::main] async fn main() { // Get the operation we're supposed to run (serve, build, export, etc.) from an environment variable @@ -180,7 +180,7 @@ pub fn main_impl(input: MainFn, server_fn: Path) -> TokenStream { } // The browser-specific `main` function - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn main() -> ::perseus::ClientReturn { ::perseus::run_client(__perseus_simple_main); Ok(()) @@ -209,7 +209,7 @@ pub fn main_export_impl(input: MainFn) -> TokenStream { // engine (all based around the default engine) let output = quote! { // The engine-specific `main` function - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[tokio::main] async fn main() { // Get the operation we're supposed to run (serve, build, export, etc.) from an environment variable @@ -219,7 +219,7 @@ pub fn main_export_impl(input: MainFn) -> TokenStream { } // The browser-specific `main` function - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn main() -> ::perseus::ClientReturn { ::perseus::run_client(__perseus_simple_main); Ok(()) @@ -249,7 +249,7 @@ pub fn browser_main_impl(input: MainFn) -> TokenStream { let output = quote! { // The browser-specific `main` function // This absolutely MUST be called `main`, otherwise the hardcodes Wasm importer will fail (and then interactivity is gone completely with a really weird error message) - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #(#attrs)* pub fn main() -> #return_type { #block @@ -266,7 +266,7 @@ pub fn engine_main_impl(input: EngineMainFn) -> TokenStream { // engine (all based around the default engine) let output = quote! { // The engine-specific `main` function - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[tokio::main] #(#attrs)* async fn main() { diff --git a/packages/perseus-macro/src/lib.rs b/packages/perseus-macro/src/lib.rs index a4486c634a..8bf125ca46 100644 --- a/packages/perseus-macro/src/lib.rs +++ b/packages/perseus-macro/src/lib.rs @@ -196,33 +196,6 @@ pub fn reactive_state(input: TokenStream) -> TokenStream { rx_state::make_rx_impl(input).into() } -/// Marks the annotated code as only to be run as part of the engine (the -/// server, the builder, the exporter, etc.). This resolves to a target-gate -/// that makes the annotated code run only on targets that are not `wasm32`. -#[proc_macro_attribute] -pub fn engine(_args: TokenStream, input: TokenStream) -> TokenStream { - let input_2: proc_macro2::TokenStream = input.into(); - quote! { - #[cfg(not(target_arch = "wasm32"))] - #input_2 - } - .into() -} - -/// Marks the annotated code as only to be run in the browser. This is the -/// opposite of (and mutually exclusive with) `#[engine]`. This resolves to a -/// target-gate that makes the annotated code run only on targets that are -/// `wasm32`. -#[proc_macro_attribute] -pub fn browser(_args: TokenStream, input: TokenStream) -> TokenStream { - let input_2: proc_macro2::TokenStream = input.into(); - quote! { - #[cfg(target_arch = "wasm32")] - #input_2 - } - .into() -} - /// A convenience macro that makes sure the given function is only defined on /// the engine-side, creating an empty function on the browser-side. Perseus /// implicitly expects most of your state generation functions to be defined in @@ -240,10 +213,10 @@ pub fn engine_only_fn(_args: TokenStream, input: TokenStream) -> TokenStream { } = parse_macro_input!(input as ItemFn); quote! { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #vis fn #ident () {} // On the engine-side, the function is unmodified - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #input_2 } .into() @@ -266,10 +239,10 @@ pub fn browser_only_fn(_args: TokenStream, input: TokenStream) -> TokenStream { } = parse_macro_input!(input as ItemFn); quote! { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #vis fn #ident () {} // One the browser-side, the function is unmodified - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #input_2 } .into() diff --git a/packages/perseus-macro/src/rx_state.rs b/packages/perseus-macro/src/rx_state.rs index 1630ff2763..3a7d3ec312 100644 --- a/packages/perseus-macro/src/rx_state.rs +++ b/packages/perseus-macro/src/rx_state.rs @@ -194,7 +194,7 @@ pub fn make_rx_impl(input: ReactiveStateDeriveInput) -> TokenStream { #unrx_field_makers } } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense<'a>(&self, cx: ::sycamore::prelude::Scope<'a>) { #suspense_commands } diff --git a/packages/perseus-warp/src/lib.rs b/packages/perseus-warp/src/lib.rs index 2eb0509eb9..6ce42d4cea 100644 --- a/packages/perseus-warp/src/lib.rs +++ b/packages/perseus-warp/src/lib.rs @@ -6,6 +6,7 @@ This is the API documentation for the `perseus-warp` package, which allows Perse documentation, and this should mostly be used as a secondary reference source. You can also find full usage examples [here](https://github.com/arctic-hen7/perseus/tree/main/examples). */ +#![cfg(engine)] #![deny(missing_docs)] #![deny(missing_debug_implementations)] diff --git a/packages/perseus/Cargo.toml b/packages/perseus/Cargo.toml index 80c8410c00..2c75cf0392 100644 --- a/packages/perseus/Cargo.toml +++ b/packages/perseus/Cargo.toml @@ -28,7 +28,7 @@ fluent-bundle = { version = "0.15", optional = true } unic-langid = { version = "0.9", optional = true } intl-memoizer = { version = "0.5", optional = true } -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +[target.'cfg(engine)'.dependencies] regex = "1" tokio = { version = "1", features = [ "fs", "io-util" ] } fs_extra = "1" @@ -37,7 +37,7 @@ urlencoding = "2.1" chrono = "0.4" minify-html-onepass = "0.10.1" -[target.'cfg(target_arch = "wasm32")'.dependencies] +[target.'cfg(client)'.dependencies] rexie = { version = "0.2", optional = true } js-sys = { version = "0.3", optional = true } # Note that this is not needed in production, but that can't be specified, so it will just be compiled away to nothing diff --git a/packages/perseus/src/error_views.rs b/packages/perseus/src/error_views.rs index de52cd8b04..d4591ed5ae 100644 --- a/packages/perseus/src/error_views.rs +++ b/packages/perseus/src/error_views.rs @@ -1,13 +1,13 @@ use crate::{errors::*, reactor::Reactor}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::{i18n::Translator, reactor::RenderMode, state::TemplateState}; use fmterr::fmt_err; use serde::{Deserialize, Serialize}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::sync::Arc; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::prelude::create_scope_immediate; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::{create_child_scope, try_use_context, ScopeDisposer}; use sycamore::{ prelude::{view, Scope}, @@ -49,7 +49,7 @@ pub struct ErrorViews { /// This will be extracted by the `PerseusApp` creation process and put in a /// place where it can be safely extracted. The replacement function /// will panic if called, so this should **never** be manually executed. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] panic_handler: Arc< dyn Fn(Scope, ClientError, ErrorContext, ErrorPosition) -> (View, View) + Send @@ -93,7 +93,7 @@ impl ErrorViews { _ => false, } }), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] panic_handler: Arc::new(handler), } } @@ -125,7 +125,7 @@ impl ErrorViews { /// Returns `true` if the given error, which must have occurred during a /// subsequent load, should be displayed as a popup, as opposed to /// occupying the entire page/widget. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) fn subsequent_err_should_be_popup(&self, err: &ClientError) -> bool { !(self.subsequent_load_determinant)(err) } @@ -171,7 +171,7 @@ impl ErrorViews { }) } } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl ErrorViews { /// Invokes the user's handling function, producing head/body views for the /// given error. From the given scope, this will determine the @@ -220,7 +220,7 @@ impl ErrorViews { ) } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl ErrorViews { /// Renders an error view on the engine-side. This takes an optional /// translator. This will return a tuple of `String`ified views for the diff --git a/packages/perseus/src/errors.rs b/packages/perseus/src/errors.rs index 50a5e38e2d..3b008b936a 100644 --- a/packages/perseus/src/errors.rs +++ b/packages/perseus/src/errors.rs @@ -1,6 +1,6 @@ #![allow(missing_docs)] -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::i18n::TranslationsManagerError; use thiserror::Error; @@ -9,10 +9,10 @@ use thiserror::Error; pub enum Error { #[error(transparent)] ClientError(#[from] ClientError), - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[error(transparent)] ServerError(#[from] ServerError), - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[error(transparent)] EngineError(#[from] EngineError), // Plugin errors could come from literally anywhere, and could have entirely arbitrary data @@ -30,7 +30,7 @@ pub struct PluginError { /// Errors that can occur in the server-side engine system (responsible for /// building the app). -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Error, Debug)] pub enum EngineError { // Many of the build/export processes return these more generic errors @@ -241,7 +241,7 @@ pub enum ClientThawError { } /// Errors that can occur in the build process or while the server is running. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Error, Debug)] pub enum ServerError { #[error("render function '{fn_name}' in template '{template_name}' failed (cause: {blame:?})")] @@ -312,7 +312,7 @@ pub enum ServerError { ClientError(#[from] ClientError), } /// Converts a server error into an HTTP status code. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub fn err_to_status_code(err: &ServerError) -> u16 { match err { ServerError::ServeError(ServeError::PageNotFound { .. }) => 404, @@ -398,7 +398,7 @@ impl std::fmt::Display for AssetType { } /// Errors that can occur while building an app. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Error, Debug)] pub enum BuildError { #[error("template '{template_name}' is missing feature '{feature_name}' (required due to its properties)")] @@ -424,7 +424,7 @@ pub enum BuildError { } /// Errors that can occur while exporting an app to static files. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Error, Debug)] pub enum ExportError { #[error("template '{template_name}' can't be exported because it depends on strategies that can't be run at build-time (only build state and build paths can be used in exportable templates)")] @@ -447,7 +447,7 @@ pub enum ServeError { PageNotFound { path: String }, #[error("both build and request states were defined for a template when only one or fewer were expected (should it be able to amalgamate states?)")] BothStatesDefined, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[error("couldn't parse revalidation datetime (try cleaning all assets)")] BadRevalidate { #[source] @@ -479,7 +479,7 @@ impl Default for ErrorBlame { /// /// *Note for those using `anyhow`: use `.map_err(|e| anyhow::anyhow!(e))?` /// to use anyhow in Perseus render functions.* -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Debug)] pub struct BlamedError { /// The underlying error. @@ -487,7 +487,7 @@ pub struct BlamedError { /// Who is to blame for the error. pub blame: ErrorBlame, } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl BlamedError { /// Converts this blamed error into an internal boxed version that is /// generic over the error type. @@ -500,7 +500,7 @@ impl BlamedError { } // We should be able to convert any error into this easily (e.g. with `?`) with // the default being to blame the server -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl From for BlamedError { fn from(error: E) -> Self { Self { @@ -511,5 +511,5 @@ impl From for BlamedError { } /// A simple wrapper for generic, boxed, blamed errors. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) type GenericBlamedError = BlamedError>; diff --git a/packages/perseus/src/i18n/mod.rs b/packages/perseus/src/i18n/mod.rs index 85601f1435..40edd4f1b2 100644 --- a/packages/perseus/src/i18n/mod.rs +++ b/packages/perseus/src/i18n/mod.rs @@ -1,16 +1,16 @@ // This module file is controlled, because it's used as an external module as // well -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod client_translations_manager; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod locale_detector; mod locales; mod translations_manager; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use client_translations_manager::ClientTranslationsManager; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use locale_detector::detect_locale; pub use locales::Locales; pub use translations_manager::{ diff --git a/packages/perseus/src/i18n/translations_manager.rs b/packages/perseus/src/i18n/translations_manager.rs index 2acef033d1..88ee352f3b 100644 --- a/packages/perseus/src/i18n/translations_manager.rs +++ b/packages/perseus/src/i18n/translations_manager.rs @@ -26,13 +26,13 @@ pub enum TranslationsManagerError { } use crate::translator::Translator; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use futures::future::join_all; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use std::collections::HashMap; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use tokio::fs::File; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use tokio::io::AsyncReadExt; /// A trait for systems that manage where to put translations. At simplest, @@ -78,7 +78,7 @@ pub trait TranslationsManager: std::fmt::Debug + Clone + Send + Sync { /// A utility function for allowing parallel futures execution. This returns a /// tuple of the locale and the translations as a JSON string. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] async fn get_translations_str_and_cache( locale: String, manager: &FsTranslationsManager, @@ -110,27 +110,27 @@ async fn get_translations_str_and_cache( /// source files cannot be updated while the system is running. #[derive(Clone, Debug)] pub struct FsTranslationsManager { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] root_path: String, /// A map of locales to cached translations. This decreases the number of /// file reads significantly for the locales specified. This /// does NOT cache dynamically, and will only cache the requested locales. /// Translators can be created when necessary from these. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] cached_translations: HashMap, /// The locales being cached for easier access. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] cached_locales: Vec, /// The file extension expected (e.g. JSON, FTL, etc). This allows for /// greater flexibility of translation engines (future). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] file_ext: String, /// This will be `true` is this translations manager is being used for an /// app that's not using i18n. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] is_dummy: bool, } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl FsTranslationsManager { /// Creates a new filesystem translations manager. You should provide a path /// like `translations/` here. You should also provide the locales you @@ -168,7 +168,7 @@ impl FsTranslationsManager { // anything #[async_trait::async_trait] impl TranslationsManager for FsTranslationsManager { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] fn new_dummy() -> Self { Self { root_path: String::new(), @@ -178,7 +178,7 @@ impl TranslationsManager for FsTranslationsManager { is_dummy: true, } } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] async fn get_translations_str_for_locale( &self, locale: String, @@ -224,7 +224,7 @@ impl TranslationsManager for FsTranslationsManager { } } } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] async fn get_translator_for_locale( &self, locale: String, @@ -258,7 +258,7 @@ impl TranslationsManager for FsTranslationsManager { Ok(translator) } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] async fn get_translator_for_translations_str( &self, locale: String, @@ -273,25 +273,25 @@ impl TranslationsManager for FsTranslationsManager { Ok(translator) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn new_dummy() -> Self { Self {} } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn get_translations_str_for_locale( &self, _locale: String, ) -> Result { Ok(String::new()) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn get_translator_for_locale( &self, _locale: String, ) -> Result { Ok(crate::i18n::Translator::new(String::new(), String::new()).unwrap()) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn get_translator_for_translations_str( &self, _locale: String, diff --git a/packages/perseus/src/init.rs b/packages/perseus/src/init.rs index ead5d2c63a..c863f9e4b6 100644 --- a/packages/perseus/src/init.rs +++ b/packages/perseus/src/init.rs @@ -1,6 +1,6 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::server::HtmlShell; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::utils::get_path_prefix_server; use crate::{ error_views::ErrorViews, @@ -10,7 +10,7 @@ use crate::{ stores::MutableStore, template::{Entity, Forever, Template}, }; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::{ error_views::{ErrorContext, ErrorPosition}, errors::ClientError, @@ -18,11 +18,11 @@ use crate::{ use crate::{errors::PluginError, template::Capsule}; use crate::{stores::ImmutableStore, template::EntityMap}; use futures::Future; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::marker::PhantomData; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use std::pin::Pin; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::rc::Rc; use std::{any::TypeId, sync::Arc}; use std::{collections::HashMap, panic::PanicInfo}; @@ -59,12 +59,12 @@ static DFLT_PSS_MAX_SIZE: usize = 25; /// us to store dummy translations managers directly, without holding futures. /// If this stores a full translations manager though, it will store it as a /// `Future`, which is later evaluated. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) enum Tm { Dummy(T), Full(Pin>>), } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl std::fmt::Debug for Tm { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Tm").finish_non_exhaustive() @@ -115,29 +115,29 @@ pub struct PerseusAppBase { /// A list of all the templates and capsules that the app uses. pub(crate) entities: EntityMap, /// The app's error pages. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) error_views: Rc>, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) error_views: Arc>, /// The maximum size for the page state store. pub(crate) pss_max_size: usize, /// 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"))] + #[cfg(engine)] pub(crate) global_state_creator: Arc, /// The internationalization information for the app. pub(crate) locales: Locales, /// The static aliases the app serves. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) static_aliases: HashMap, /// The plugins the app uses. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) plugins: Arc, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) plugins: Rc, /// The app's immutable store. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) immutable_store: ImmutableStore, /// The HTML template that'll be used to render the app into. This must be /// static, but can be generated or sourced in any way. Note that this MUST @@ -145,36 +145,36 @@ pub struct PerseusAppBase { /// is. pub(crate) index_view: String, /// The app's mutable store. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) mutable_store: M, /// The app's translations manager, expressed as a function yielding a /// `Future`. This is only ever needed on the server-side, and can't be set /// up properly on the client-side because we can't use futures in the /// app initialization in Wasm. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) translations_manager: Tm, /// The location of the directory to use for static assets that will placed /// under the URL `/.perseus/static/`. By default, this is the `static/` /// directory at the root of your project. Note that the directory set /// here will only be used if it exists. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) static_dir: String, /// A handler for panics on the browser-side. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) panic_handler: Option>, /// A duplicate of the app's error handling function intended for panic /// handling. This must be extracted as an owned value and provided in a /// thread-safe manner to the panic hook system. /// /// This is in an `Arc` because panic hooks are `Fn`s, not `FnOnce`s. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) panic_handler_view: Arc< dyn Fn(Scope, ClientError, ErrorContext, ErrorPosition) -> (View, View) + Send + Sync, >, // We need this on the client-side to account for the unused type parameters - #[cfg(target_arch = "wasm32")] + #[cfg(client)] _marker: PhantomData<(M, T)>, } impl std::fmt::Debug for PerseusAppBase { @@ -190,7 +190,7 @@ impl std::fmt::Debug for Perse .field("locale", &self.locales) .field("plugins", &self.plugins) .field("index_view", &self.index_view); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { return debug .field( @@ -202,7 +202,7 @@ impl std::fmt::Debug for Perse ) .finish_non_exhaustive(); } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { return debug .field("global_state_creator", &self.global_state_creator) @@ -233,7 +233,7 @@ impl PerseusAppBase { /// This is asynchronous because it creates a translations manager in the /// background. // It makes no sense to implement `Default` on this, so we silence Clippy deliberately - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] #[allow(clippy::new_without_default)] pub fn new() -> Self { Self::new_with_mutable_store(FsMutableStore::new("./dist/mutable".to_string())) @@ -251,7 +251,7 @@ impl PerseusAppBase { /// This is asynchronous because it creates a translations manager in the /// background. // It makes no sense to implement `Default` on this, so we silence Clippy deliberately - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #[allow(clippy::new_without_default)] pub fn new() -> Self { Self::new_wasm() @@ -265,13 +265,13 @@ impl PerseusAppBase { /// using [`FsTranslationsManager`] but when you don't know if your app is /// using i18n or not (almost always middleware). pub fn locales_lit_and_translations_manager(mut self, locales: Locales) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] let using_i18n = locales.using_i18n; self.locales = locales; // We only handle the translations manager on the server-side (it doesn't exist // on the client-side) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { // If we're using i18n, do caching stuff // If not, use a dummy translations manager @@ -339,7 +339,7 @@ impl PerseusAppBase { // building error_views: Default::default(), pss_max_size: DFLT_PSS_MAX_SIZE, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] 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...) @@ -349,34 +349,34 @@ impl PerseusAppBase { using_i18n: false, }, // By default, we won't serve any static content outside the `static/` directory - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] static_aliases: HashMap::new(), // By default, we won't use any plugins - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] plugins: Arc::new(Plugins::new()), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] plugins: Rc::new(Plugins::new()), - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] immutable_store: ImmutableStore::new("./dist".to_string()), - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] mutable_store, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] translations_manager: Tm::Dummy(T::new_dummy()), // Many users won't need anything fancy in the index view, so we provide a default index_view: DFLT_INDEX_VIEW.to_string(), - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] static_dir: "./static".to_string(), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] panic_handler: None, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] panic_handler_view: ErrorViews::unlocalized_development_default().take_panic_handler(), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] _marker: PhantomData, } } /// Internal function for Wasm initialization. This should never be called /// by the user! - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #[doc(hidden)] fn new_wasm() -> Self { Self { @@ -422,7 +422,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn static_dir(mut self, val: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.static_dir = val.to_string(); } @@ -543,13 +543,13 @@ impl PerseusAppBase { // error views. #[allow(unused_mut)] pub fn error_views(mut self, mut val: ErrorViews) -> Self { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { let panic_handler = val.take_panic_handler(); self.error_views = Rc::new(val); self.panic_handler_view = panic_handler; } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.error_views = Arc::new(val); } @@ -560,7 +560,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn global_state_creator(mut self, val: GlobalStateCreator) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.global_state_creator = Arc::new(val); } @@ -615,7 +615,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn translations_manager(mut self, val: impl Future + 'static) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.translations_manager = Tm::Full(Box::pin(val)); } @@ -632,7 +632,7 @@ impl PerseusAppBase { }; // All translations manager must implement this function, which is designed for // this exact purpose - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.translations_manager = Tm::Dummy(T::new_dummy()); } @@ -645,7 +645,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn static_aliases(mut self, val: HashMap) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.static_aliases = val; } @@ -657,7 +657,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn static_alias(mut self, url: &str, resource: &str) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] // We don't elaborate the alias to an actual filesystem path until the getter self.static_aliases .insert(url.to_string(), resource.to_string()); @@ -666,11 +666,11 @@ impl PerseusAppBase { /// Sets the plugins that the app will use. See [`Plugins`] for /// further details. pub fn plugins(mut self, val: Plugins) -> Self { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { self.plugins = Rc::new(val); } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.plugins = Arc::new(val); } @@ -684,7 +684,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn mutable_store(mut self, val: M) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.mutable_store = val; } @@ -695,7 +695,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn immutable_store(mut self, val: ImmutableStore) -> Self { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { self.immutable_store = val; } @@ -771,7 +771,7 @@ impl PerseusAppBase { #[allow(unused_variables)] #[allow(unused_mut)] pub fn panic_handler(mut self, val: impl Fn(&PanicInfo) + Send + Sync + 'static) -> Self { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] { self.panic_handler = Some(Box::new(val)); } @@ -793,7 +793,7 @@ impl PerseusAppBase { // /// Gets the directory containing static assets to be hosted under the URL // /// `/.perseus/static/`. // // TODO Plugin action for this? - // #[cfg(not(target_arch = "wasm32"))] + // #[cfg(engine)] // pub fn get_static_dir(&self) -> String { // self.static_dir.to_string() // } @@ -804,7 +804,7 @@ impl PerseusAppBase { /// HTML shell produced, which can only be overridden with a control plugin /// (though you should really never do this in Perseus, which targets /// HTML on the web). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] 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 @@ -816,7 +816,7 @@ impl PerseusAppBase { /// 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(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn get_html_shell( index_view_str: String, root: &str, @@ -908,12 +908,12 @@ impl PerseusAppBase { // self.entities.clone() // } // /// Gets the [`ErrorViews`] used in the app. This returns an `Rc`. - // #[cfg(target_arch = "wasm32")] + // #[cfg(client)] // pub fn get_error_views(&self) -> Rc> { // self.error_views.clone() // } // /// Gets the [`ErrorViews`] used in the app. This returns an `Arc`. - // #[cfg(not(target_arch = "wasm32"))] + // #[cfg(engine)] // pub fn get_atomic_error_views(&self) -> Arc> { // self.error_views.clone() // } @@ -924,7 +924,7 @@ impl PerseusAppBase { // } // /// Gets the [`GlobalStateCreator`]. This can't be directly modified by // /// plugins because of reactive type complexities. - // #[cfg(not(target_arch = "wasm32"))] + // #[cfg(engine)] // pub fn get_global_state_creator(&self) -> Arc { // self.global_state_creator.clone() // } @@ -945,7 +945,7 @@ impl PerseusAppBase { /// /// This involves evaluating the future stored for the translations manager, /// and so this consumes `self`. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn get_translations_manager(self) -> T { match self.translations_manager { Tm::Dummy(tm) => tm, @@ -953,7 +953,7 @@ impl PerseusAppBase { } } /// Gets the [`ImmutableStore`]. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn get_immutable_store(&self) -> Result { let immutable_store = self.immutable_store.clone(); let immutable_store = self @@ -968,17 +968,17 @@ impl PerseusAppBase { // /// Gets the [`MutableStore`]. This can't be modified by plugins due to // /// trait complexities, so plugins should instead expose a function that // /// the user can use to manually set it. - // #[cfg(not(target_arch = "wasm32"))] + // #[cfg(engine)] // pub fn get_mutable_store(&self) -> M { // self.mutable_store.clone() // } // /// Gets the plugins registered for the app. - // #[cfg(not(target_arch = "wasm32"))] + // #[cfg(engine)] // pub fn get_plugins(&self) -> Arc { // self.plugins.clone() // } // /// Gets the plugins registered for the app. - // #[cfg(target_arch = "wasm32")] + // #[cfg(client)] // pub fn get_plugins(&self) -> Rc { // self.plugins.clone() // } @@ -987,7 +987,7 @@ impl PerseusAppBase { /// potential security risks in production (we don't want to /// accidentally serve an arbitrary in a production environment where a path /// may point to somewhere evil, like an alias to `/etc/passwd`). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn get_static_aliases(&self) -> Result, PluginError> { let mut static_aliases = self.static_aliases.clone(); // This will return a map of plugin name to another map of static aliases that @@ -1039,7 +1039,7 @@ impl PerseusAppBase { /// # Future panics /// If this is called more than once, the view panic handler will panic when /// called. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn take_panic_handlers( &mut self, ) -> ( diff --git a/packages/perseus/src/lib.rs b/packages/perseus/src/lib.rs index 37f58926fa..0e097ed812 100644 --- a/packages/perseus/src/lib.rs +++ b/packages/perseus/src/lib.rs @@ -24,7 +24,7 @@ documentation, and this should mostly be used as a secondary reference source. Y /// Utilities for working with the engine-side, particularly with regards to /// setting up the entrypoint for your app's build/export/server processes. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub mod engine; /// Utilities surrounding `ErrorViews` and their management. pub mod error_views; @@ -39,7 +39,7 @@ pub mod plugins; 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(not(target_arch = "wasm32"))] +#[cfg(engine)] pub mod server; /// Utilities for working with Perseus' state platform. pub mod state; @@ -52,7 +52,7 @@ pub mod template; /// General utilities that may be useful while building Perseus apps. pub mod utils; -#[cfg(all(feature = "client-helpers", target_arch = "wasm32"))] +#[cfg(all(feature = "client-helpers", client))] mod client; mod init; mod page_data; @@ -63,46 +63,46 @@ pub mod path; pub mod reactor; mod translator; /// The core of the Perseus state generation system. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub mod turbine; // The rest of this file is devoted to module structuring // Re-exports -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub use http; -#[cfg(not(target_arch = "wasm32"))] +#[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(not(target_arch = "wasm32"))] +#[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(target_arch = "wasm32")] +#[cfg(client)] pub type Request = (); #[cfg(feature = "macros")] pub use perseus_macro::*; // Browser-side only -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use crate::utils::checkpoint; -#[cfg(all(feature = "client-helpers", target_arch = "wasm32"))] +#[cfg(all(feature = "client-helpers", client))] pub use client::{run_client, ClientReturn}; /// Internal utilities for lower-level work. -#[cfg(not(target_arch = "wasm32"))] +#[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(target_arch = "wasm32")] +#[cfg(client)] #[doc(hidden)] pub mod log { pub use wasm_bindgen::JsValue; @@ -116,7 +116,7 @@ pub mod log { /// `View`), 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(not(target_arch = "wasm32"))] +#[cfg(engine)] pub type PerseusNodeType = sycamore::web::SsrNode; /// An alias for `DomNode`, `HydrateNode`, or `SsrNode`, depending on the /// `hydrate` feature flag and compilation target. @@ -125,7 +125,7 @@ pub type PerseusNodeType = sycamore::web::SsrNode; /// `View`), 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(target_arch = "wasm32", not(feature = "hydrate")))] +#[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. @@ -134,7 +134,7 @@ pub type PerseusNodeType = sycamore::web::DomNode; /// `View`), 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(target_arch = "wasm32", feature = "hydrate"))] +#[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 @@ -143,7 +143,7 @@ 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(not(target_arch = "wasm32"))] + #[cfg(engine)] pub use crate::errors::{BlamedError, ErrorBlame}; pub use crate::init::*; pub use crate::reactor::Reactor; @@ -152,16 +152,13 @@ pub mod prelude { pub use sycamore::web::Html; pub use sycamore_router::{navigate, navigate_replace}; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub use crate::utils::{cache_fallible_res, cache_res}; pub use crate::web_log; - #[cfg(feature = "macros")] - pub use crate::{ - auto_scope, browser, browser_main, browser_only_fn, engine, engine_main, engine_only_fn, - main, main_export, template_rx, test, ReactiveState, UnreactiveState, - }; #[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; } diff --git a/packages/perseus/src/plugins/functional.rs b/packages/perseus/src/plugins/functional.rs index 887c53d857..d311881715 100644 --- a/packages/perseus/src/plugins/functional.rs +++ b/packages/perseus/src/plugins/functional.rs @@ -1,10 +1,10 @@ use super::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::errors::Error; use crate::errors::PluginError; use std::any::Any; use std::collections::HashMap; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use std::sync::Arc; /// An action which can be taken by many plugins. When run, a functional action @@ -89,13 +89,13 @@ pub struct FunctionalPluginActions { /// `PerseusApp`. pub settings_actions: FunctionalPluginSettingsActions, /// Actions pertaining to the build process. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub build_actions: FunctionalPluginBuildActions, /// Actions pertaining to the export process. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub export_actions: FunctionalPluginExportActions, /// Actions pertaining to the process of exporting an error page. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub export_error_page_actions: FunctionalPluginExportErrorPageActions, /// Actions pertaining to the server. pub server_actions: FunctionalPluginServerActions, @@ -150,7 +150,7 @@ pub struct FunctionalPluginHtmlShellActions { /// Functional actions that pertain to the build process. Note that these /// actions are not available for the build stage of the export process, and /// those should be registered separately. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Default, Debug)] pub struct FunctionalPluginBuildActions { /// Runs before the build process. @@ -161,7 +161,7 @@ pub struct FunctionalPluginBuildActions { pub after_failed_build: FunctionalPluginAction, ()>, } /// Functional actions that pertain to the export process. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Default, Debug)] pub struct FunctionalPluginExportActions { /// Runs before the export process. @@ -187,7 +187,7 @@ pub struct FunctionalPluginExportActions { pub after_successful_export: FunctionalPluginAction<(), ()>, } /// Functional actions that pertain to the process of exporting an error page. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Default, Debug)] pub struct FunctionalPluginExportErrorPageActions { /// Runs before the process of exporting an error page, providing the HTTP diff --git a/packages/perseus/src/plugins/plugins_list.rs b/packages/perseus/src/plugins/plugins_list.rs index badb54fa21..e0ec528fc0 100644 --- a/packages/perseus/src/plugins/plugins_list.rs +++ b/packages/perseus/src/plugins/plugins_list.rs @@ -43,17 +43,15 @@ impl Plugins { // We allow unused variables and the like for linting because otherwise any // errors in Wasm compilation will show these up, which is annoying pub fn plugin( - #[cfg_attr(target_arch = "wasm32", allow(unused_mut))] mut self, + #[cfg_attr(client, allow(unused_mut))] mut self, // This is a function so that it never gets called if we're compiling for Wasm, which means // Rust eliminates it as dead code! - #[cfg_attr(target_arch = "wasm32", allow(unused_variables))] plugin: impl Fn() -> Plugin - + Send - + Sync, - #[cfg_attr(target_arch = "wasm32", allow(unused_variables))] plugin_data: D, + #[cfg_attr(client, allow(unused_variables))] plugin: impl Fn() -> Plugin + Send + Sync, + #[cfg_attr(client, allow(unused_variables))] plugin_data: D, ) -> Self { // If we're compiling for Wasm, plugins that don't run on the client side // shouldn't be added (they'll then be eliminated as dead code) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { let plugin = plugin(); // If the plugin can run on the client-side, it should use `.client_plugin()` diff --git a/packages/perseus/src/reactor/error.rs b/packages/perseus/src/reactor/error.rs index 6894866890..11877c914a 100644 --- a/packages/perseus/src/reactor/error.rs +++ b/packages/perseus/src/reactor/error.rs @@ -5,7 +5,7 @@ use crate::{ template::BrowserNodeType, utils::{render_or_hydrate, replace_head}, }; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use std::rc::Rc; use std::{panic::PanicInfo, sync::Arc}; use sycamore::{ diff --git a/packages/perseus/src/reactor/global_state.rs b/packages/perseus/src/reactor/global_state.rs index 69e2750677..6aafab7b7a 100644 --- a/packages/perseus/src/reactor/global_state.rs +++ b/packages/perseus/src/reactor/global_state.rs @@ -1,5 +1,5 @@ use super::Reactor; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::state::FrozenGlobalState; use crate::{ errors::*, @@ -96,7 +96,7 @@ impl Reactor { /// Note: on the engine-side, there is no such thing as frozen state, and /// the active state will always be empty, so this will simply return /// `None`. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn get_held_global_state(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, @@ -128,7 +128,7 @@ impl Reactor { self.get_active_global_state::() } } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] fn get_held_global_state(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, @@ -141,7 +141,7 @@ impl Reactor { /// register anything in the state store. This may return an error on a /// downcast failure (which is probably the user's fault for providing /// the wrong type argument, but it's still an invariant failure). - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn get_active_global_state(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, @@ -155,7 +155,7 @@ impl Reactor { /// the thaw preferences have already been accounted for. /// /// This assumes that the app actually supports global state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn get_frozen_global_state_and_register(&self) -> Result, ClientError> where S: MakeRx + Serialize + DeserializeOwned, diff --git a/packages/perseus/src/reactor/mod.rs b/packages/perseus/src/reactor/mod.rs index 8519d71344..4d5d707fd4 100644 --- a/packages/perseus/src/reactor/mod.rs +++ b/packages/perseus/src/reactor/mod.rs @@ -1,26 +1,26 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod error; mod global_state; -#[cfg(all(feature = "hsr", debug_assertions, target_arch = "wasm32"))] +#[cfg(all(feature = "hsr", debug_assertions, client))] mod hsr; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod initial_load; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod render_mode; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod start; mod state; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod subsequent_load; mod widget_state; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use initial_load::InitialView; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use render_mode::{RenderMode, RenderStatus}; // --- Common imports --- -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::template::{BrowserNodeType, EntityMap}; use crate::{ i18n::Translator, @@ -34,7 +34,7 @@ use sycamore::{ // --- Engine-side imports --- // --- Browser-side imports --- -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::{ error_views::ErrorViews, errors::ClientError, @@ -46,17 +46,17 @@ use crate::{ state::{FrozenApp, ThawPrefs}, stores::MutableStore, }; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use serde::{de::DeserializeOwned, Serialize}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use serde_json::Value; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::{ cell::{Cell, RefCell}, collections::HashMap, rc::Rc, }; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::{ reactive::{create_rc_signal, RcSignal}, view::View, @@ -73,7 +73,7 @@ pub struct Reactor { /// preloads. pub(crate) state_store: PageStateStore, /// The router state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub router_state: RouterState, /// The user-provided global state, stored with similar mechanics to the /// state store, although optimised. @@ -86,58 +86,58 @@ pub struct Reactor { /// The `bool` in here will be set to `true` if this was created through /// HSR, which has slightly more lenient thawing procedures to allow for /// data model changes. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] frozen_app: Rc>>, /// Whether or not this page is the very first to have been rendered since /// the browser loaded the app. This will be reset on full reloads, and is /// used internally to determine whether or not we should look for /// stored HSR state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) is_first: Cell, /// The app's *full* render configuration. Note that a subset of this /// is contained in the [`RenderMode`] on the engine-side for widget /// rendering. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) render_cfg: HashMap, /// The app's templates and capsules for use in routing. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) entities: EntityMap, /// The app's locales. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) locales: Locales, /// The browser-side translations manager. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] translations_manager: ClientTranslationsManager, /// The app's error views. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) error_views: Rc>, /// A reactive container for the current page-wide view. This will usually /// contain the contents of the current page, but it may also contain a /// page-wide error. This will be wrapped in a router. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] current_view: RcSignal>, /// A reactive container for any popup errors. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] popup_error_view: RcSignal>, /// The app's root div ID. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] root: String, // --- Engine-side only --- - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) render_mode: RenderMode, /// The currently active translator. On the browser-side, this is handled by /// the more fully-fledged [`ClientTranslationsManager`]. /// /// This is provided to the engine-side reactor on instantiation. This can /// be `None` in certain error view renders. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] translator: Option, } // This uses window variables set by the HTML shell, so it should never be used // on the engine-side -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl TryFrom> for Reactor { @@ -220,7 +220,7 @@ impl Reactor { /// /// On the engine-side, this will return `None` under certain error /// conditions. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn try_get_translator(&self) -> Option { self.translations_manager.get_translator() } @@ -231,7 +231,7 @@ impl Reactor { /// /// On the engine-side, this will return `None` under certain error /// conditions. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn try_get_translator(&self) -> Option { self.translator.clone() } @@ -250,7 +250,7 @@ impl Reactor { } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl Reactor { /// Initializes a new [`Reactor`] on the engine-side. pub(crate) fn engine( @@ -276,7 +276,7 @@ impl Reactor { /// The possible states a window variable injected by the server/export process /// can be found in. -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) enum WindowVariable { /// It existed and coudl be deserialized into the correct type. Some(T), @@ -287,7 +287,7 @@ pub(crate) enum WindowVariable { /// string to be deserialized, found a boolean instead). Malformed, } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with window variables that have @@ -311,7 +311,7 @@ impl WindowVariable { Self::Some(val_typed) } } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with boolean window variables. @@ -333,7 +333,7 @@ impl WindowVariable { } } } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl WindowVariable { /// Gets the window variable of the given name, attempting to fetch it as /// the given type. This will only work with `String` window variables. diff --git a/packages/perseus/src/reactor/render_mode.rs b/packages/perseus/src/reactor/render_mode.rs index 32d511d131..02389e9930 100644 --- a/packages/perseus/src/reactor/render_mode.rs +++ b/packages/perseus/src/reactor/render_mode.rs @@ -31,7 +31,7 @@ impl Default for RenderStatus { /// /// Ths render mode is primarily used to inform the non-delayed widgets of how /// they should render. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] #[derive(Clone, Debug)] pub(crate) enum RenderMode { /// We're rendering at build-time. Any non-delayed widgets should render if diff --git a/packages/perseus/src/reactor/state.rs b/packages/perseus/src/reactor/state.rs index 92cb07e2e8..a0dfe9551f 100644 --- a/packages/perseus/src/reactor/state.rs +++ b/packages/perseus/src/reactor/state.rs @@ -4,20 +4,20 @@ use crate::{ path::*, state::{AnyFreeze, MakeRx, MakeUnrx, TemplateState}, }; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::{ router::RouterLoadState, state::{Freeze, FrozenApp, ThawPrefs}, }; use serde::{de::DeserializeOwned, Serialize}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; use sycamore::web::Html; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore_router::navigate; // Explicitly prevent the user from trying to freeze on the engine-side -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl Freeze for Reactor { fn freeze(&self) -> String { // This constructs a `FrozenApp`, which has everything the thawing reactor will @@ -41,7 +41,7 @@ impl Freeze for Reactor { } } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl Reactor { /// Commands Perseus to 'thaw' the app from the given frozen state. You'll /// also need to provide preferences for thawing, which allow you to control @@ -309,7 +309,7 @@ impl Reactor { /// Note: on the engine-side, there is no such thing as frozen state, and /// the active state will always be empty, so this will simply return /// `None`. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(super) fn get_held_state( &self, url: &PathMaybeWithLocale, @@ -345,7 +345,7 @@ impl Reactor { Ok(self.get_active_state::(url)) } } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(super) fn get_held_state( &self, _url: &PathMaybeWithLocale, @@ -360,7 +360,7 @@ impl Reactor { /// Attempts to the get the active state for a page or widget. Of course, /// this does not register anything in the state store. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn get_active_state(&self, url: &PathMaybeWithLocale) -> Option where S: MakeRx, @@ -371,7 +371,7 @@ impl Reactor { /// Attempts to extract the frozen state for the given page from any /// currently registered frozen app, registering what it finds. This /// assumes that the thaw preferences have already been accounted for. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn get_frozen_state_and_register( &self, url: &PathMaybeWithLocale, diff --git a/packages/perseus/src/reactor/widget_state.rs b/packages/perseus/src/reactor/widget_state.rs index 4afd37f04c..65e32f9621 100644 --- a/packages/perseus/src/reactor/widget_state.rs +++ b/packages/perseus/src/reactor/widget_state.rs @@ -1,4 +1,4 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use std::sync::Arc; use super::Reactor; @@ -15,11 +15,11 @@ use sycamore::{ web::Html, }; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use crate::template::PreloadInfo; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::create_signal; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore_futures::spawn_local_scoped; impl Reactor { @@ -38,12 +38,12 @@ impl Reactor { app_cx: Scope<'a>, path: PathMaybeWithLocale, #[allow(unused_variables)] caller_path: PathMaybeWithLocale, - #[cfg(target_arch = "wasm32")] capsule_name: String, + #[cfg(client)] capsule_name: String, template_state: TemplateState, // Empty on the browser-side props: P, - #[cfg(target_arch = "wasm32")] preload_info: PreloadInfo, + #[cfg(client)] preload_info: PreloadInfo, view_fn: F, - #[cfg(target_arch = "wasm32")] fallback_fn: &Arc View + Send + Sync>, + #[cfg(client)] fallback_fn: &Arc View + Send + Sync>, ) -> Result<(View, ScopeDisposer<'a>), ClientError> where // Note: these bounds replicate those for `.view_with_state()`, except the app lifetime is @@ -67,7 +67,7 @@ impl Reactor { } // We need to asynchronously fetch the state from the server, which doesn't work // ergonomically with the rest of the code, so we just break out entirely - #[cfg(target_arch = "wasm32")] + #[cfg(client)] None => { return { let view = create_signal(app_cx, View::empty()); @@ -144,7 +144,7 @@ impl Reactor { }; } // On the engine-side, this is impossible (we cannot be instructed to fetch) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] None => unreachable!(), } } @@ -162,12 +162,12 @@ impl Reactor { app_cx: Scope<'a>, path: PathMaybeWithLocale, #[allow(unused_variables)] caller_path: PathMaybeWithLocale, - #[cfg(target_arch = "wasm32")] capsule_name: String, + #[cfg(client)] capsule_name: String, template_state: TemplateState, // Empty on the browser-side props: P, - #[cfg(target_arch = "wasm32")] preload_info: PreloadInfo, + #[cfg(client)] preload_info: PreloadInfo, view_fn: F, - #[cfg(target_arch = "wasm32")] fallback_fn: &Arc View + Send + Sync>, + #[cfg(client)] fallback_fn: &Arc View + Send + Sync>, ) -> Result<(View, ScopeDisposer<'a>), ClientError> where F: Fn(Scope, S, P) -> View + Send + Sync + 'static, @@ -186,7 +186,7 @@ impl Reactor { } // We need to asynchronously fetch the state from the server, which doesn't work // ergonomically with the rest of the code, so we just break out entirely - #[cfg(target_arch = "wasm32")] + #[cfg(client)] None => { return { let view = create_signal(app_cx, View::empty()); @@ -259,7 +259,7 @@ impl Reactor { }; } // On the engine-side, this is impossible (we cannot be instructed to fetch) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] None => unreachable!(), } } @@ -287,7 +287,7 @@ impl Reactor { { if let Some(held_state) = self.get_held_state::(url, true)? { Ok(Some(held_state)) - } else if cfg!(target_arch = "wasm32") { + } else if cfg!(client) { // On the browser-side, the given server state is empty, and we need to check // the preload match self.state_store.contains(url) { diff --git a/packages/perseus/src/router/mod.rs b/packages/perseus/src/router/mod.rs index 989b8dd3ae..244d37fafa 100644 --- a/packages/perseus/src/router/mod.rs +++ b/packages/perseus/src/router/mod.rs @@ -1,18 +1,18 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod app_route; mod match_route; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod page_disposer; mod route_verdict; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod router_state; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use app_route::PerseusRoute; pub(crate) use match_route::match_route; pub use route_verdict::{FullRouteInfo, FullRouteVerdict, RouteInfo, RouteVerdict}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use router_state::{RouterLoadState, RouterState}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use page_disposer::PageDisposer; diff --git a/packages/perseus/src/state/global_state.rs b/packages/perseus/src/state/global_state.rs index c628f0c02c..ead720418b 100644 --- a/packages/perseus/src/state/global_state.rs +++ b/packages/perseus/src/state/global_state.rs @@ -1,41 +1,41 @@ use super::rx_state::AnyFreeze; use super::TemplateState; use super::{MakeRx, MakeUnrx}; -#[cfg(not(target_arch = "wasm32"))] // To suppress warnings +#[cfg(engine)] // To suppress warnings use crate::errors::*; use crate::errors::{ClientError, ClientInvariantError}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::make_async_trait; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::template::{BlamedGeneratorResult, GeneratorResult}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::utils::AsyncFnReturn; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::Request; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use futures::Future; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use serde::de::DeserializeOwned; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use serde::Deserialize; use serde::Serialize; use std::cell::RefCell; use std::rc::Rc; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateBuildFnType, Result, locale: String ); -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateRequestFnType, Result, locale: String, req: Request ); -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateAmalgamationFnType, Result, @@ -44,20 +44,20 @@ make_async_trait!( request_state: TemplateState ); -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateBuildUserFnType< S: Serialize + DeserializeOwned + MakeRx, V: Into< GeneratorResult > >, V, locale: String ); -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateRequestUserFnType< S: Serialize + DeserializeOwned + MakeRx, V: Into< BlamedGeneratorResult > >, V, locale: String, req: Request ); -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] make_async_trait!( GlobalStateAmalgamationUserFnType< S: Serialize + DeserializeOwned + MakeRx, V: Into< BlamedGeneratorResult > >, V, @@ -67,13 +67,13 @@ make_async_trait!( ); /// The type of functions that generate global state at build-time. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub type GlobalStateBuildFn = Box; /// The type of functions that generate global state at build-time. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub type GlobalStateRequestFn = Box; /// The type of functions that generate global state at build-time. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub type GlobalStateAmalgamationFn = Box; /// A creator for global state. This stores user-provided functions that will be @@ -86,16 +86,16 @@ pub type GlobalStateAmalgamationFn = Box, /// The function that creates state at request-time. This is roughly /// equivalent to the *request state* strategy for templates. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] request: Option, /// The function that amalgamates state from build-time and request-time. /// This is roughly equivalent to the *state amalgamation* strategy for /// templates. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] amalgamation: Option, } impl std::fmt::Debug for GlobalStateCreator { @@ -110,7 +110,7 @@ impl GlobalStateCreator { } /// Adds a function to generate global state at build-time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn build_state_fn( mut self, val: impl GlobalStateBuildUserFnType + Clone + Send + Sync + 'static, @@ -134,13 +134,13 @@ impl GlobalStateCreator { self } /// Adds a function to generate global state at build-time. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn build_state_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Adds a function to generate global state at request-time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn request_state_fn( mut self, val: impl GlobalStateRequestUserFnType + Clone + Send + Sync + 'static, @@ -164,13 +164,13 @@ impl GlobalStateCreator { self } /// Adds a function to generate global state at request-time. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn request_state_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Adds a function to amalgamate build-time and request-time global state. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn amalgamate_states_fn( mut self, val: impl GlobalStateAmalgamationUserFnType + Clone + Send + Sync + 'static, @@ -216,13 +216,13 @@ impl GlobalStateCreator { self } /// Adds a function to amalgamate build-time and request-time global state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn amalgamate_states_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Gets the global state at build-time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn get_build_state(&self, locale: String) -> Result { if let Some(get_build_state) = &self.build { get_build_state.call(locale).await @@ -235,7 +235,7 @@ impl GlobalStateCreator { } } /// Gets the global state at request-time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn get_request_state( &self, locale: String, @@ -253,7 +253,7 @@ impl GlobalStateCreator { } /// Amalgamates global state that was generated at build-time with that /// generated at request-time, according to custom user-provided logic. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn amalgamate_states( &self, locale: String, @@ -274,18 +274,18 @@ impl GlobalStateCreator { } /// Checks if this state needs to do anything on requests for it. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_request_state(&self) -> bool { self.request.is_some() } /// Checks if this state needs to do anything at build time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_build_state(&self) -> bool { self.build.is_some() } /// Checks if this state has custom logic to amalgamate build and /// request states if both are generated. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn can_amalgamate_states(&self) -> bool { self.amalgamation.is_some() } @@ -348,7 +348,7 @@ impl std::fmt::Debug for GlobalState { } /// Frozen global state. -#[cfg(target_arch = "wasm32")] +#[cfg(client)] #[derive(Serialize, Deserialize, Debug, Clone)] pub enum FrozenGlobalState { /// There is state that should be instantiated. @@ -366,7 +366,7 @@ pub enum FrozenGlobalState { /// this purpose. Used, } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] impl From<&GlobalStateType> for FrozenGlobalState { fn from(val: &GlobalStateType) -> Self { match val { diff --git a/packages/perseus/src/state/mod.rs b/packages/perseus/src/state/mod.rs index 674998f2b8..c315d59d8c 100644 --- a/packages/perseus/src/state/mod.rs +++ b/packages/perseus/src/state/mod.rs @@ -1,19 +1,19 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod freeze; // This has `FrozenApp` etc. mod global_state; mod rx_result; mod rx_state; mod state_generator_info; mod state_store; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod suspense; mod template_state; // #[cfg(feature = "rx-collections")] pub mod rx_collections; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use freeze::{FrozenApp, PageThawPrefs, ThawPrefs}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use global_state::FrozenGlobalState; pub use global_state::{GlobalState, GlobalStateCreator, GlobalStateType}; pub use rx_result::{RxResult, RxResultRx, SerdeInfallible}; @@ -22,18 +22,18 @@ pub use state_generator_info::{BuildPaths, StateGeneratorInfo}; pub use state_store::{PageStateStore, PssContains, PssEntry, PssState}; pub use template_state::{TemplateState, TemplateStateWithType, UnknownStateType}; -#[cfg(all(feature = "idb-freezing", target_arch = "wasm32"))] +#[cfg(all(feature = "idb-freezing", client))] mod freeze_idb; -#[cfg(all(feature = "idb-freezing", target_arch = "wasm32"))] +#[cfg(all(feature = "idb-freezing", client))] pub use freeze_idb::{IdbError, IdbFrozenStateStore}; // We'll allow live reloading (of which HSR is a subset) if it's feature-enabled // and we're in development mode -#[cfg(all(feature = "live-reload", debug_assertions, target_arch = "wasm32"))] +#[cfg(all(feature = "live-reload", debug_assertions, client))] mod live_reload; -#[cfg(all(feature = "live-reload", debug_assertions, target_arch = "wasm32"))] +#[cfg(all(feature = "live-reload", debug_assertions, client))] pub(crate) use live_reload::connect_to_reload_server; -#[cfg(all(feature = "live-reload", debug_assertions, target_arch = "wasm32"))] +#[cfg(all(feature = "live-reload", debug_assertions, client))] pub(crate) use live_reload::force_reload; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use suspense::{compute_nested_suspense, compute_suspense}; diff --git a/packages/perseus/src/state/rx_collections/rx_hash_map.rs b/packages/perseus/src/state/rx_collections/rx_hash_map.rs index 604ce053b7..40a6ad3d1a 100644 --- a/packages/perseus/src/state/rx_collections/rx_hash_map.rs +++ b/packages/perseus/src/state/rx_collections/rx_hash_map.rs @@ -3,7 +3,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use std::hash::Hash; use std::ops::Deref; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -59,7 +59,7 @@ where ) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense(&self, cx: Scope) {} } // --- Dereferencing --- diff --git a/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs b/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs index 8b1e5065a6..e8890c0504 100644 --- a/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs +++ b/packages/perseus/src/state/rx_collections/rx_hash_map_nested.rs @@ -3,7 +3,7 @@ use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::collections::HashMap; use std::hash::Hash; use std::ops::Deref; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; /// A reactive version of [`Vec`] that uses nested reactivity on its elements. @@ -57,7 +57,7 @@ where ) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense(&self, cx: Scope) { for elem in self.0.values() { elem.compute_suspense(cx); diff --git a/packages/perseus/src/state/rx_collections/rx_vec.rs b/packages/perseus/src/state/rx_collections/rx_vec.rs index 953f5169a1..f30fddc3de 100644 --- a/packages/perseus/src/state/rx_collections/rx_vec.rs +++ b/packages/perseus/src/state/rx_collections/rx_vec.rs @@ -1,7 +1,7 @@ use crate::state::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; use sycamore::reactive::{create_rc_signal, RcSignal}; @@ -48,7 +48,7 @@ where ) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense(&self, cx: Scope) {} } // --- Dereferencing --- diff --git a/packages/perseus/src/state/rx_collections/rx_vec_nested.rs b/packages/perseus/src/state/rx_collections/rx_vec_nested.rs index 7abc6b79cd..d742e4daad 100644 --- a/packages/perseus/src/state/rx_collections/rx_vec_nested.rs +++ b/packages/perseus/src/state/rx_collections/rx_vec_nested.rs @@ -1,7 +1,7 @@ use crate::state::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; /// A reactive version of [`Vec`] that uses nested reactivity on its elements. @@ -46,7 +46,7 @@ where RxVecNested(self.0.into_iter().map(|x| x.make_unrx()).collect()) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense(&self, cx: Scope) { for elem in self.0.iter() { elem.compute_suspense(cx); diff --git a/packages/perseus/src/state/rx_result.rs b/packages/perseus/src/state/rx_result.rs index 392059947c..641087c9ba 100644 --- a/packages/perseus/src/state/rx_result.rs +++ b/packages/perseus/src/state/rx_result.rs @@ -1,7 +1,7 @@ use super::{Freeze, MakeRx, MakeUnrx}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use std::ops::Deref; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; use sycamore::prelude::{create_rc_signal, RcSignal}; @@ -76,7 +76,7 @@ where // fields, is fine. When that top-level field is *also* suspended, that is // very much not okay! (We would have multiple handlers operating on the // same fields, which is not a pattern I want to encourage.) - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense<'a>(&self, _cx: Scope<'a>) {} } impl Freeze for RxResultRx diff --git a/packages/perseus/src/state/rx_state.rs b/packages/perseus/src/state/rx_state.rs index 2654bd0834..d81ec9ded7 100644 --- a/packages/perseus/src/state/rx_state.rs +++ b/packages/perseus/src/state/rx_state.rs @@ -1,6 +1,6 @@ use serde::{Deserialize, Serialize}; use std::any::Any; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::Scope; /// A trait for `struct`s that can be made reactive. Typically, this will be @@ -55,7 +55,7 @@ pub trait MakeUnrx { /// If you're implementing `MakeUnrx` manually, you can usually leave the /// body of this function empty unless you're using the suspended state /// system. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense<'a>(&self, cx: Scope<'a>); } @@ -126,7 +126,7 @@ impl Deserialize<'de> + UnreactiveState + Clone> MakeUnr self.0 } // Suspense is not allowed on unreactive state - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn compute_suspense(&self, _cx: Scope) {} } // And, since the underlying type can be serialized, implement `Freeze` diff --git a/packages/perseus/src/state/state_generator_info.rs b/packages/perseus/src/state/state_generator_info.rs index 79b04ebc7a..840abb64f2 100644 --- a/packages/perseus/src/state/state_generator_info.rs +++ b/packages/perseus/src/state/state_generator_info.rs @@ -37,7 +37,7 @@ impl StateGeneratorInfo /// Transform the underlying [`TemplateStateWithType`] into one with a /// different type. Once this is done, `.to_concrete()` can be used to /// get this type out of the container. - #[cfg(not(target_arch = "wasm32"))] // Just to silence clippy (if you need to remove this, do) + #[cfg(engine)] // Just to silence clippy (if you need to remove this, do) pub(crate) fn change_type( self, ) -> StateGeneratorInfo { diff --git a/packages/perseus/src/state/state_store.rs b/packages/perseus/src/state/state_store.rs index 1bfec89859..8005139a7c 100644 --- a/packages/perseus/src/state/state_store.rs +++ b/packages/perseus/src/state/state_store.rs @@ -2,7 +2,7 @@ use crate::errors::{ClientError, ClientInvariantError}; use crate::page_data::PageDataPartial; use crate::path::*; use crate::state::AnyFreeze; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use serde_json::Value; use std::cell::RefCell; use std::collections::HashMap; @@ -262,7 +262,7 @@ impl PageStateStore { /// # Panics /// This function will panic if the given page and widget paths are not /// already registered in the state store. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) fn declare_dependency( &self, widget_path: &PathMaybeWithLocale, @@ -291,7 +291,7 @@ impl PageStateStore { /// Note that this should generally be called through `Reactor`, to avoid /// having to manually collect the required arguments. // Note that this function bears striking resemblance to the subsequent load system! - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) async fn preload( &self, path: &PathWithoutLocale, @@ -370,7 +370,7 @@ impl PageStateStore { /// Adds the given widget to the preload list so it can be later accessed /// during the initial load render. This is not used for widgets in /// subsequently loaded pages, which are fetched separately. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) fn add_initial_widget(&self, url: PathMaybeWithLocale, state: Value) { let mut preloaded = self.preloaded.borrow_mut(); // Widgets never have heads @@ -560,12 +560,12 @@ impl PssEntry { self.head = Some(head); } /// Declares a widget that this page/widget depends on, by its path. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn add_dependency(&mut self, path: PathMaybeWithLocale) { self.dependencies.push(path); } /// Declares a page/widget that this widget is used by, by its path. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn add_dependent(&mut self, path: PathMaybeWithLocale) { self.dependents.push(path); } diff --git a/packages/perseus/src/stores/immutable.rs b/packages/perseus/src/stores/immutable.rs index fe81994b0c..79e8a733d3 100644 --- a/packages/perseus/src/stores/immutable.rs +++ b/packages/perseus/src/stores/immutable.rs @@ -1,6 +1,6 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::errors::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use tokio::{ fs::{create_dir_all, File}, io::{AsyncReadExt, AsyncWriteExt}, @@ -19,13 +19,13 @@ use tokio::{ /// change use a [`MutableStore`](super::MutableStore) instead. #[derive(Clone, Debug)] pub struct ImmutableStore { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] root_path: String, } impl ImmutableStore { /// Creates a new immutable store. You should provide a path like `dist` /// here. Note that any trailing slashes will be automatically stripped. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn new(root_path: String) -> Self { let root_path = root_path .strip_prefix('/') @@ -37,12 +37,12 @@ impl ImmutableStore { /// /// This is designed to be used in particular by the engine to work out /// where to put static assets and the like when exporting. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn get_path(&self) -> &str { &self.root_path } /// Reads the given asset from the filesystem asynchronously. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn read(&self, name: &str) -> Result { let asset_path = format!("{}/{}", self.root_path, name); let file_res = File::open(&asset_path).await; @@ -83,7 +83,7 @@ impl ImmutableStore { /// Writes the given asset to the filesystem asynchronously. This must only /// be used at build-time, and must not be changed afterward. Note that this /// will automatically create any missing parent directories. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub async fn write(&self, name: &str, content: &str) -> Result<(), StoreError> { let asset_path = format!("{}/{}", self.root_path, name); let mut dir_tree: Vec<&str> = asset_path.split('/').collect(); diff --git a/packages/perseus/src/stores/mutable.rs b/packages/perseus/src/stores/mutable.rs index 320fba4621..236761be4f 100644 --- a/packages/perseus/src/stores/mutable.rs +++ b/packages/perseus/src/stores/mutable.rs @@ -1,5 +1,5 @@ use crate::errors::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use tokio::{ fs::{create_dir_all, File}, io::{AsyncReadExt, AsyncWriteExt}, @@ -44,23 +44,23 @@ pub trait MutableStore: std::fmt::Debug + Clone + Send + Sync { /// parent directories automatically. #[derive(Clone, Debug)] pub struct FsMutableStore { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] root_path: String, } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] impl FsMutableStore { /// Creates a new filesystem configuration manager. You should provide a /// path like `dist/mutable` here. Make sure that this is not the same /// path as the [`ImmutableStore`](super::ImmutableStore), as this will /// cause potentially problematic overlap between the two systems. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn new(root_path: String) -> Self { Self { root_path } } } #[async_trait::async_trait] impl MutableStore for FsMutableStore { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] async fn read(&self, name: &str) -> Result { let asset_path = format!("{}/{}", self.root_path, name); let file_res = File::open(&asset_path).await; @@ -99,7 +99,7 @@ impl MutableStore for FsMutableStore { } } // This creates a directory structure as necessary - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] async fn write(&self, name: &str, content: &str) -> Result<(), StoreError> { let asset_path = format!("{}/{}", self.root_path, name); let mut dir_tree: Vec<&str> = asset_path.split('/').collect(); @@ -135,11 +135,11 @@ impl MutableStore for FsMutableStore { Ok(()) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn read(&self, _name: &str) -> Result { Ok(String::new()) } - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn write(&self, _name: &str, _content: &str) -> Result<(), StoreError> { Ok(()) } diff --git a/packages/perseus/src/template/capsule.rs b/packages/perseus/src/template/capsule.rs index ae817d2390..9355a9bcfe 100644 --- a/packages/perseus/src/template/capsule.rs +++ b/packages/perseus/src/template/capsule.rs @@ -114,7 +114,7 @@ impl Capsule { template_inner.is_capsule = true; // Produce nice errors to make it clear that heads and headers don't work with // capsules - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] { assert!( template_inner.head.is_none(), @@ -144,7 +144,7 @@ impl Capsule { /// used for widgets. /// /// This should NOT be used to render pages! - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #[allow(clippy::too_many_arguments)] pub(crate) fn render_widget_for_template_client( &self, @@ -170,7 +170,7 @@ impl Capsule { /// server-side ONLY. This takes the scope from a previous call of /// `.render_for_template_server()`, assuming the reactor has already /// been fully instantiated. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) fn render_widget_for_template_server( &self, path: PathMaybeWithLocale, @@ -265,9 +265,9 @@ impl CapsuleInner { { self.template_inner.view = Box::new(|_, _, _, _| panic!("attempted to call template rendering logic for widget")); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] let entity_name = self.template_inner.get_path(); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] let fallback_fn = self.fallback.clone(); // `Arc`ed, heaven help us self.capsule_view = Box::new( #[allow(unused_variables)] @@ -277,14 +277,14 @@ impl CapsuleInner { app_cx, path, caller_path, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] entity_name.clone(), template_state, props, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] preload_info, val.clone(), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fallback_fn.as_ref().unwrap(), ) }, @@ -301,9 +301,9 @@ impl CapsuleInner { { self.template_inner.view = Box::new(|_, _, _, _| panic!("attempted to call template rendering logic for widget")); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] let entity_name = self.template_inner.get_path(); - #[cfg(target_arch = "wasm32")] + #[cfg(client)] let fallback_fn = self.fallback.clone(); // `Arc`ed, heaven help us self.capsule_view = Box::new( #[allow(unused_variables)] @@ -313,14 +313,14 @@ impl CapsuleInner { app_cx, path, caller_path, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] entity_name.clone(), template_state, props, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] preload_info, val.clone(), - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fallback_fn.as_ref().unwrap(), ) }, @@ -344,7 +344,7 @@ impl CapsuleInner { // caching reactor.register_no_state(&path, true); // And declare the relationship between the widget and its caller - #[cfg(target_arch = "wasm32")] + #[cfg(client)] reactor.state_store.declare_dependency(&path, &caller_path); // Nicely, if this is a widget, this means there need be no network requests diff --git a/packages/perseus/src/template/core/getters.rs b/packages/perseus/src/template/core/getters.rs index 2f7b5520e2..5fa7b7a5ee 100644 --- a/packages/perseus/src/template/core/getters.rs +++ b/packages/perseus/src/template/core/getters.rs @@ -1,5 +1,5 @@ use super::TemplateInner; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::utils::ComputedDuration; use sycamore::web::Html; @@ -24,53 +24,53 @@ impl TemplateInner { } } /// Gets the interval after which the template will next revalidate. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn get_revalidate_interval(&self) -> Option { self.revalidate_after.clone() } // Render characteristic checkers /// Checks if this template can revalidate existing prerendered templates. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn revalidates(&self) -> bool { self.should_revalidate.is_some() || self.revalidate_after.is_some() } /// Checks if this template can revalidate existing prerendered templates /// after a given time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn revalidates_with_time(&self) -> bool { self.revalidate_after.is_some() } /// Checks if this template can revalidate existing prerendered templates /// based on some given logic. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn revalidates_with_logic(&self) -> bool { self.should_revalidate.is_some() } /// Checks if this template can render more templates beyond those paths it /// explicitly defines. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_incremental(&self) -> bool { self.incremental_generation } /// Checks if this template is a template to generate paths beneath it. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_build_paths(&self) -> bool { self.get_build_paths.is_some() } /// Checks if this template needs to do anything on requests for it. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_request_state(&self) -> bool { self.get_request_state.is_some() } /// Checks if this template needs to do anything at build time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn uses_build_state(&self) -> bool { self.get_build_state.is_some() } /// Checks if this template has custom logic to amalgamate build and /// request states if both are generated. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn can_amalgamate_states(&self) -> bool { self.amalgamate_states.is_some() } @@ -78,7 +78,7 @@ impl TemplateInner { /// templates will be rendered using SSG. Basic templates can /// still modify headers (which could hypothetically be using global state /// that's dependent on server-side generation). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn is_basic(&self) -> bool { !self.uses_build_paths() && !self.uses_build_state() diff --git a/packages/perseus/src/template/core/mod.rs b/packages/perseus/src/template/core/mod.rs index cee231fc82..e725f598a0 100644 --- a/packages/perseus/src/template/core/mod.rs +++ b/packages/perseus/src/template/core/mod.rs @@ -14,10 +14,10 @@ use std::ops::Deref; pub(crate) use entity::{Entity, EntityMap, Forever}; pub(crate) use utils::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use super::fn_types::*; use super::TemplateFn; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::utils::ComputedDuration; use sycamore::{prelude::create_scope, view::View, web::Html}; @@ -76,7 +76,7 @@ pub struct TemplateInner { /// the same way as `template`, but will always be rendered to a string, /// which will then be interpolated directly into the ``, /// so reactivity here will not work! - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) head: Option, /// A function to be run when the server returns an HTTP response. This /// should return headers for said response, given the template's state. @@ -84,7 +84,7 @@ pub struct TemplateInner { /// revalidation. This will only be run on successful responses, and /// does have the power to override existing headers. By default, this will /// create sensible cache control headers. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) set_headers: Option, /// A function that generates the information to begin building a template. /// This is responsible for generating all the paths that will built for @@ -92,7 +92,7 @@ pub struct TemplateInner { /// incremental generation), along with the generation of any extra /// state that may be collectively shared by other state generating /// functions. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_build_paths: Option, /// Defines whether or not any new paths that match this template will be /// prerendered and cached in production. This allows you to @@ -102,24 +102,24 @@ pub struct TemplateInner { /// requires `get_build_paths`. Note that the template root will NOT /// be rendered on demand, and must be explicitly defined if it's wanted. It /// can use a different template. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] incremental_generation: bool, /// A function that gets the initial state to use to prerender the template /// at build time. This will be passed the path of the template, and /// will be run for any sub-paths. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_build_state: Option, /// A function that will run on every request to generate a state for that /// request. This allows server-side-rendering. This can be used with /// `get_build_state`, though custom amalgamation logic must be provided. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_request_state: Option, /// A function to be run on every request to check if a template prerendered /// at build-time should be prerendered again. If used with /// `revalidate_after`, this function will only be run after that time /// period. This function will not be parsed anything specific to the /// request that invoked it. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] should_revalidate: Option, /// A length of time after which to prerender the template again. The given /// duration will be waited for, and the next request after it will lead @@ -128,13 +128,13 @@ pub struct TemplateInner { /// (meaning if you expect a weekly re-rendering cycle for all pages, /// they'd likely all be out of sync, you'd need to manually implement /// that with `should_revalidate`). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] revalidate_after: Option, /// Custom logic to amalgamate potentially different states generated at /// build and request time. This is only necessary if your template uses /// both `build_state` and `request_state`. If not specified and both are /// generated, request state will be prioritized. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] amalgamate_states: Option, /// Whether or not this template is actually a capsule. This impacts /// significant aspects of internal handling. @@ -167,23 +167,23 @@ impl TemplateInner { // Because of the scope disposer return type, this isn't as trivial as an empty function view: Box::new(|_, _, _, _| Ok((View::empty(), create_scope(|_| {})))), // Unlike `template`, this may not be set at all (especially in very simple apps) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] head: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] set_headers: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_build_paths: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] incremental_generation: false, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_build_state: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] get_request_state: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] should_revalidate: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] revalidate_after: None, - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] amalgamate_states: None, // There is no mechanism to set this to `true`, except through the `Capsule` struct is_capsule: false, @@ -207,9 +207,9 @@ impl TemplateInner { // those feature settings through /// An alias for `DomNode` or `HydrateNode`, depending on the feature flags /// enabled. -#[cfg(all(not(feature = "hydrate"), target_arch = "wasm32"))] +#[cfg(all(not(feature = "hydrate"), client))] pub(crate) type BrowserNodeType = sycamore::prelude::DomNode; /// An alias for `DomNode` or `HydrateNode`, depending on the feature flags /// enabled. -#[cfg(all(feature = "hydrate", target_arch = "wasm32"))] +#[cfg(all(feature = "hydrate", client))] pub(crate) type BrowserNodeType = sycamore::prelude::HydrateNode; diff --git a/packages/perseus/src/template/core/renderers.rs b/packages/perseus/src/template/core/renderers.rs index 89a1ffe758..a3a16a4324 100644 --- a/packages/perseus/src/template/core/renderers.rs +++ b/packages/perseus/src/template/core/renderers.rs @@ -1,26 +1,26 @@ use super::utils::PreloadInfo; use crate::errors::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::i18n::Translator; use crate::path::PathMaybeWithLocale; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::reactor::Reactor; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::reactor::RenderMode; use crate::state::TemplateState; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::state::{BuildPaths, StateGeneratorInfo, UnknownStateType}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::template::default_headers; use crate::template::TemplateInner; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::Request; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use http::HeaderMap; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::prelude::ScopeDisposer; use sycamore::web::Html; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::web::SsrNode; use sycamore::{prelude::Scope, view::View}; @@ -29,7 +29,7 @@ impl TemplateInner { /// client-side ONLY. This takes in an existing global state. /// /// This should NOT be used to render widgets! - #[cfg(target_arch = "wasm32")] + #[cfg(client)] #[allow(clippy::too_many_arguments)] pub(crate) fn render_for_template_client<'a>( &self, @@ -56,7 +56,7 @@ impl TemplateInner { /// Executes the user-given function that renders the template on the /// server-side ONLY. This automatically initializes an isolated global /// state. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) fn render_for_template_server( &self, path: PathMaybeWithLocale, @@ -85,7 +85,7 @@ impl TemplateInner { /// returning a string to be interpolated manually. Reactivity in this /// function will not take effect due to this string rendering. Note that /// this function will provide a translator context. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) fn render_head_str( &self, state: TemplateState, @@ -120,7 +120,7 @@ impl TemplateInner { Ok(prerendered) } /// Gets the list of templates that should be prerendered for at build-time. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn get_build_paths(&self) -> Result { if let Some(get_build_paths) = &self.get_build_paths { get_build_paths.call().await @@ -137,7 +137,7 @@ impl TemplateInner { /// `.get_build_paths()`. This also needs the locale being rendered to so /// that more complex applications like custom documentation systems can /// be enabled. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn get_build_state( &self, info: StateGeneratorInfo, @@ -158,7 +158,7 @@ impl TemplateInner { /// the render. Errors here can be caused by either the server or the /// client, so the user must specify an [`ErrorBlame`]. This is also passed /// the locale being rendered to. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn get_request_state( &self, info: StateGeneratorInfo, @@ -181,7 +181,7 @@ impl TemplateInner { /// This takes a separate build state and request state to ensure there are /// no `None`s for either of the states. This will only be called if both /// states are generated. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn amalgamate_states( &self, info: StateGeneratorInfo, @@ -205,7 +205,7 @@ impl TemplateInner { /// network access etc., and can really do whatever it likes. Errors here /// can be caused by either the server or the client, so the /// user must specify an [`ErrorBlame`]. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) async fn should_revalidate( &self, info: StateGeneratorInfo, @@ -230,7 +230,7 @@ impl TemplateInner { /// translations, as localized headers are very much real. Locale /// detection pages are considered internal to Perseus, and therefore do /// not have support for user headers (at this time). - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) fn get_headers( &self, state: TemplateState, diff --git a/packages/perseus/src/template/core/setters.rs b/packages/perseus/src/template/core/setters.rs index 7e20dd7a25..0abf9e3890 100644 --- a/packages/perseus/src/template/core/setters.rs +++ b/packages/perseus/src/template/core/setters.rs @@ -3,17 +3,17 @@ use crate::utils::PerseusDuration; use sycamore::web::Html; // This file is all engine-side functions, and browser-side dummies -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use super::super::fn_types::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::state::{BuildPaths, MakeRx}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::state::{StateGeneratorInfo, TemplateState, UnknownStateType}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use http::HeaderMap; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use serde::{de::DeserializeOwned, Serialize}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::{prelude::Scope, view::View, web::SsrNode}; impl TemplateInner { @@ -28,7 +28,7 @@ impl TemplateInner { /// /// This is for heads that do not require state. Those that do should use /// `.head_with_state()` instead. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn head>>>( mut self, val: impl Fn(Scope) -> V + Send + Sync + 'static, @@ -46,14 +46,14 @@ impl TemplateInner { /// /// This is for heads that do not require state. Those that do should use /// `.head_with_state()` instead. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn head(self, _val: impl Fn() + 'static) -> Self { self } /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// does not need state. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn set_headers>>( mut self, val: impl Fn(Scope) -> V + Send + Sync + 'static, @@ -70,13 +70,13 @@ impl TemplateInner { /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// does not need state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn set_headers(self, _val: impl Fn() + 'static) -> Self { self } /// Enables the *build paths* strategy with the given function. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn build_paths_fn>>( mut self, val: impl GetBuildPathsUserFnType + Clone + Send + Sync + 'static, @@ -95,25 +95,25 @@ impl TemplateInner { self } /// Enables the *build paths* strategy with the given function. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn build_paths_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Enables the *incremental generation* strategy. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn incremental_generation(mut self) -> Self { self.incremental_generation = true; self } /// Enables the *incremental generation* strategy. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn incremental_generation(self) -> Self { self } /// Enables the *build state* strategy with the given function. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn build_state_fn( mut self, val: impl GetBuildStateUserFnType + Clone + Send + Sync + 'static, @@ -143,13 +143,13 @@ impl TemplateInner { self } /// Enables the *build state* strategy with the given function. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn build_state_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Enables the *request state* strategy with the given function. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn request_state_fn( mut self, val: impl GetRequestStateUserFnType + Clone + Send + Sync + 'static, @@ -179,14 +179,14 @@ impl TemplateInner { self } /// Enables the *request state* strategy with the given function. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn request_state_fn(self, _val: impl Fn() + 'static) -> Self { self } /// Enables the *revalidation* strategy (logic variant) with the given /// function. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn should_revalidate_fn( mut self, val: impl ShouldRevalidateUserFnType + Clone + Send + Sync + 'static, @@ -213,7 +213,7 @@ impl TemplateInner { } /// Enables the *revalidation* strategy (logic variant) with the given /// function. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn should_revalidate_fn(self, _val: impl Fn() + 'static) -> Self { self } @@ -229,7 +229,7 @@ impl TemplateInner { /// - M: month (30 days used here, 12M ≠ 1y!), /// - y: year (365 days always, leap years ignored, if you want them add /// them as days) - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn revalidate_after(mut self, val: I) -> Self { let computed_duration = match val.into_computed() { Ok(val) => val, @@ -251,7 +251,7 @@ impl TemplateInner { /// - M: month (30 days used here, 12M ≠ 1y!), /// - y: year (365 days always, leap years ignored, if you want them add /// them as days) - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn revalidate_after(self, _val: I) -> Self { self } @@ -262,7 +262,7 @@ impl TemplateInner { /// rationalizing the two into one single state to be sent to the client, /// and this will be run just after the request state function /// completes. See [`States`] for further details. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn amalgamate_states_fn( mut self, val: impl AmalgamateStatesUserFnType + Clone + Send + Sync + 'static, @@ -316,7 +316,7 @@ impl TemplateInner { /// rationalizing the two into one single state to be sent to the client, /// and this will be run just after the request state function /// completes. See [`States`] for further details. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn amalgamate_states_fn(self, _val: impl Fn() + 'static) -> Self { self } diff --git a/packages/perseus/src/template/core/state_setters.rs b/packages/perseus/src/template/core/state_setters.rs index c1b0bb72dd..ea3593af2a 100644 --- a/packages/perseus/src/template/core/state_setters.rs +++ b/packages/perseus/src/template/core/state_setters.rs @@ -1,18 +1,18 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use super::super::fn_types::*; use super::TemplateInner; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use crate::errors::*; use crate::{ reactor::Reactor, state::{AnyFreeze, MakeRx, MakeUnrx, UnreactiveState}, }; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use http::HeaderMap; use serde::{de::DeserializeOwned, Serialize}; use sycamore::prelude::BoundedScope; use sycamore::prelude::{create_child_scope, create_ref}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::web::SsrNode; use sycamore::{prelude::Scope, view::View, web::Html}; @@ -51,7 +51,7 @@ impl TemplateInner { let mut view = View::empty(); let disposer = ::sycamore::reactive::create_child_scope(app_cx, |child_cx| { // Compute suspended states - #[cfg(target_arch = "wasm32")] + #[cfg(client)] intermediate_state.compute_suspense(child_cx); view = val(child_cx, create_ref(child_cx, intermediate_state)); @@ -117,7 +117,7 @@ impl TemplateInner { /// /// This is for heads that do require state. Those that do not should use /// `.head()` instead. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn head_with_state( mut self, val: impl Fn(Scope, S) -> V + Send + Sync + 'static, @@ -160,7 +160,7 @@ impl TemplateInner { /// /// This is for heads that do require state. Those that do not should use /// `.head()` instead. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn head_with_state(self, _val: impl Fn() + 'static) -> Self { self } @@ -168,7 +168,7 @@ impl TemplateInner { /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// requires knowing the state. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub fn set_headers_with_state( mut self, val: impl Fn(Scope, S) -> V + Send + Sync + 'static, @@ -208,7 +208,7 @@ impl TemplateInner { /// Sets the function to set headers. This will override Perseus' inbuilt /// header defaults. This should only be used when your header-setting /// requires knowing the state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn set_headers_with_state(self, _val: impl Fn() + 'static) -> Self { self } diff --git a/packages/perseus/src/template/core/utils.rs b/packages/perseus/src/template/core/utils.rs index e4436ef1d0..28b5fb3ca0 100644 --- a/packages/perseus/src/template/core/utils.rs +++ b/packages/perseus/src/template/core/utils.rs @@ -4,8 +4,8 @@ /// This exists on the engine-side for type convenience, but only has fields /// on the browser-side. pub(crate) struct PreloadInfo { - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) locale: String, - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) was_incremental_match: bool, } diff --git a/packages/perseus/src/template/mod.rs b/packages/perseus/src/template/mod.rs index 142300579b..86c2b89974 100644 --- a/packages/perseus/src/template/mod.rs +++ b/packages/perseus/src/template/mod.rs @@ -1,24 +1,24 @@ mod core; // So called because this contains what is essentially the core exposed logic of Perseus -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod default_headers; // mod render_ctx; mod capsule; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod fn_types; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod states; mod widget_component; pub use self::core::*; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub use fn_types::*; /* There are a lot of render function traits in here, there's no * point in spelling them all out */ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use default_headers::default_headers; // pub use render_ctx::RenderCtx; // pub(crate) use render_ctx::{RenderMode, RenderStatus}; pub use capsule::Capsule; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use states::States; use crate::{errors::ClientError, path::PathMaybeWithLocale, state::TemplateState}; diff --git a/packages/perseus/src/template/render_ctx.rs b/packages/perseus/src/template/render_ctx.rs index a734221b34..0ce5b7d3c7 100644 --- a/packages/perseus/src/template/render_ctx.rs +++ b/packages/perseus/src/template/render_ctx.rs @@ -1,4 +1,4 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use super::BrowserNodeType; use super::{ArcTemplateMap, TemplateState, TemplateStateWithType}; use crate::{PathMaybeWithLocale, PathWithoutLocale, errors::*}; @@ -14,7 +14,7 @@ use serde_json::Value; use sycamore::prelude::{provide_context, use_context, Scope}; use sycamore::web::{Html, SsrNode}; use sycamore_router::navigate; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use std::collections::HashMap; @@ -67,7 +67,7 @@ pub struct RenderCtx { /// **Warning:** these don't exist on the engine-side! But, there, you /// should always return a build-time error rather than produce a page /// with an error in it. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub error_pages: Rc>, // --- PRIVATE FIELDS --- // Any users accessing these are *extremely* likely to shoot themselves in the foot! @@ -75,26 +75,26 @@ pub struct RenderCtx { /// the browser loaded the app. This will be reset on full reloads, and is /// used internally to determine whether or not we should look for /// stored HSR state. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) is_first: Rc>, /// The locales, for use in routing. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) locales: crate::i18n::Locales, /// The map of all templates in the app, for use in routing. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) templates: crate::template::TemplateMap, /// The render configuration, for use in routing. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) render_cfg: Rc>, /// The client-side translations manager. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub(crate) translations_manager: crate::i18n::ClientTranslationsManager, /// The mode we're currently rendering in. This will be used primarily in widget rendering. /// /// While a user could *hypothetically* render in a manner that's dependent on this, that is /// never going to be a good idea, since the internals of this could change in any release. Hence, /// we keep it private to the crate. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] pub(crate) render_mode: RenderMode, } impl Freeze for RenderCtx { @@ -117,7 +117,7 @@ impl Freeze for RenderCtx { serde_json::to_string(&frozen_app).unwrap() } } -#[cfg(not(target_arch = "wasm32"))] // To prevent foot-shooting +#[cfg(engine)] // To prevent foot-shooting impl RenderCtx { /// Initializes a new `RenderCtx` on the server-side with the given global /// state and set of widget states. @@ -145,7 +145,7 @@ impl RenderCtx { /// /// Note also that this will automatically extract global state from page /// variables. - #[cfg(target_arch = "wasm32")] // To prevent foot-shooting + #[cfg(client)] // To prevent foot-shooting pub(crate) fn new( pss_max_size: usize, locales: crate::i18n::Locales, @@ -197,7 +197,7 @@ impl RenderCtx { /// preloading is not hardcoded, use `.try_preload()` instead. // Conveniently, we can use the lifetime mechanics of knowing that the render context // is registered on the given scope to ensure that the future works out - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn preload<'a, 'b: 'a>(&'b self, cx: Scope<'a>, url: &PathMaybeWithLocale) { use fmterr::fmt_err; @@ -224,7 +224,7 @@ impl RenderCtx { /// preloading is not hardcoded, use `.try_route_preload()` instead. // Conveniently, we can use the lifetime mechanics of knowing that the render context // is registered on the given scope to ensure that the future works out - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub fn route_preload<'a, 'b: 'a>(&'b self, cx: Scope<'a>, url: &PathMaybeWithLocale) { use fmterr::fmt_err; @@ -237,20 +237,20 @@ impl RenderCtx { /// A version of `.preload()` that returns a future that can resolve to an /// error. If the path you're preloading is not hardcoded, you should /// use this. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub async fn try_preload(&self, url: &PathMaybeWithLocale) -> Result<(), ClientError> { self._preload(url, false).await } /// A version of `.route_preload()` that returns a future that can resolve /// to an error. If the path you're preloading is not hardcoded, you /// should use this. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] pub async fn try_route_preload(&self, url: &PathMaybeWithLocale) -> Result<(), ClientError> { self._preload(url, true).await } /// Preloads the given URL from the server and caches it, preventing /// future network requests to fetch that page. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] async fn _preload(&self, path: &PathMaybeWithLocale, is_route_preload: bool) -> Result<(), ClientError> { use crate::router::{match_route, RouteVerdict}; @@ -720,7 +720,7 @@ impl RenderCtx { /// /// Note that apps without global state will get `Some(..)` of an empty template /// state here. -#[cfg(target_arch = "wasm32")] +#[cfg(client)] fn get_global_state() -> Option { let val_opt = web_sys::window().unwrap().get("__PERSEUS_GLOBAL_STATE"); let js_obj = match val_opt { diff --git a/packages/perseus/src/template/widget_component.rs b/packages/perseus/src/template/widget_component.rs index a008463d47..99427fe43a 100644 --- a/packages/perseus/src/template/widget_component.rs +++ b/packages/perseus/src/template/widget_component.rs @@ -1,7 +1,7 @@ use std::any::TypeId; use crate::path::PathWithoutLocale; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::prelude::create_child_scope; use sycamore::{prelude::Scope, view::View, web::Html}; @@ -107,7 +107,7 @@ impl Capsule { let path = path.strip_suffix('/').unwrap_or(&path); let path = PathWithoutLocale(path.to_string()); - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] return { let mut view = View::empty(); if delayed { @@ -127,7 +127,7 @@ impl Capsule { }; // On the browser-side, delayed and non-delayed are the same (it just matters as // to what's been preloaded) - #[cfg(target_arch = "wasm32")] + #[cfg(client)] return { let view = self.browser_widget(cx, path, props); view @@ -137,7 +137,7 @@ impl Capsule { /// The internal browser-side logic for widgets, both delayed and not. /// /// See `.__widget()` for explanation of transmutation. - #[cfg(target_arch = "wasm32")] + #[cfg(client)] fn browser_widget(&self, cx: Scope, path: PathWithoutLocale, props: P) -> View { use crate::{ errors::ClientInvariantError, @@ -230,7 +230,7 @@ impl Capsule { /// The internal engine-side logic for widgets. /// /// See `.widget()` for explanation of transmutation. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(engine)] fn engine_widget(&self, cx: Scope, path: PathWithoutLocale, props: P) -> View { use std::sync::Arc; diff --git a/packages/perseus/src/utils/decode_time_str.rs b/packages/perseus/src/utils/decode_time_str.rs index 552bd86885..6d91bd07ac 100644 --- a/packages/perseus/src/utils/decode_time_str.rs +++ b/packages/perseus/src/utils/decode_time_str.rs @@ -1,4 +1,4 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod engine { use super::InvalidDuration; use chrono::Utc; @@ -81,7 +81,7 @@ mod engine { } } } -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod browser { use super::InvalidDuration; use std::time; @@ -116,9 +116,9 @@ mod browser { #[derive(Debug)] pub struct InvalidDuration; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use browser::{ComputedDuration, PerseusDuration}; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub use engine::{ComputedDuration, PerseusDuration}; // // We can convert from our duration type into the standard library's diff --git a/packages/perseus/src/utils/log.rs b/packages/perseus/src/utils/log.rs index 51e21c661d..2a69626b5c 100644 --- a/packages/perseus/src/utils/log.rs +++ b/packages/perseus/src/utils/log.rs @@ -1,7 +1,7 @@ /// Logs the given `format!`-style data to the browser's console, or to stdout /// as usual on the server. #[macro_export] -#[cfg(target_arch = "wasm32")] +#[cfg(client)] macro_rules! web_log { ($format_str:literal $(, $data:expr)*) => { $crate::log::log_js_value( @@ -15,7 +15,7 @@ macro_rules! web_log { /// Logs the given `format!`-style data to the browser's console, or to stdout /// on the server. #[macro_export] -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] macro_rules! web_log { ($format_str:literal $(, $data:expr)*) => { println!($format_str $(, $data)*) diff --git a/packages/perseus/src/utils/mod.rs b/packages/perseus/src/utils/mod.rs index 525e29bad0..f3cc723e3a 100644 --- a/packages/perseus/src/utils/mod.rs +++ b/packages/perseus/src/utils/mod.rs @@ -1,36 +1,36 @@ -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod async_fn_trait; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod cache_res; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod checkpoint; mod decode_time_str; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod fetch; mod log; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] mod minify; mod path_prefix; mod render; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] mod replace_head; mod test; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use async_fn_trait::AsyncFnReturn; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub use cache_res::{cache_fallible_res, cache_res}; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub use checkpoint::checkpoint; pub use decode_time_str::{ComputedDuration, InvalidDuration, PerseusDuration}; /* These have dummy equivalents for the browser */ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use fetch::fetch; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use minify::minify; pub use path_prefix::*; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use render::render_or_hydrate; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) use render::ssr_fallible; -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub(crate) use replace_head::replace_head; diff --git a/packages/perseus/src/utils/path_prefix.rs b/packages/perseus/src/utils/path_prefix.rs index 4e2d6bc9fa..e428a4cfec 100644 --- a/packages/perseus/src/utils/path_prefix.rs +++ b/packages/perseus/src/utils/path_prefix.rs @@ -3,7 +3,7 @@ /// something as changeable as this into the final binary. Hence however, that /// variable must be the same as what's set in `` (done automatically). /// Trailing forward slashes will be trimmed automatically. -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub fn get_path_prefix_server() -> String { use std::env; @@ -17,7 +17,7 @@ pub fn get_path_prefix_server() -> String { /// Gets the path prefix to apply in the browser. This uses the HTML `` /// element, which would be required anyway to make Sycamore's router co-operate /// with a relative path hosting. -#[cfg(target_arch = "wasm32")] +#[cfg(client)] pub fn get_path_prefix_client() -> String { use wasm_bindgen::JsCast; use web_sys::{HtmlBaseElement, Url}; diff --git a/packages/perseus/src/utils/render.rs b/packages/perseus/src/utils/render.rs index dbeb28cd12..e3fb09dddd 100644 --- a/packages/perseus/src/utils/render.rs +++ b/packages/perseus/src/utils/render.rs @@ -1,8 +1,8 @@ -#[cfg(target_arch = "wasm32")] +#[cfg(client)] use sycamore::utils::render::insert; -#[cfg(all(not(feature = "hydrate"), target_arch = "wasm32"))] +#[cfg(all(not(feature = "hydrate"), client))] use sycamore::web::DomNode; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] use sycamore::web::SsrNode; use sycamore::{prelude::Scope, view::View}; @@ -17,7 +17,7 @@ use sycamore::{prelude::Scope, view::View}; // TODO Make sure hydration will work when it's targeted at a blank canvas... // XXX This is *highly* dependent on internal Sycamore implementation // details! (TODO PR for `hydrate_to_with_scope` etc.) -#[cfg(target_arch = "wasm32")] +#[cfg(client)] #[allow(unused_variables)] pub(crate) fn render_or_hydrate( cx: Scope, @@ -74,7 +74,7 @@ pub(crate) fn render_or_hydrate( /// automatically. // XXX This is *highly* dependent on internal Sycamore implementation // details! -#[cfg(not(target_arch = "wasm32"))] +#[cfg(engine)] pub(crate) fn ssr_fallible( view_fn: impl FnOnce(Scope) -> Result, E>, ) -> Result {