feat: use cargo-leptos for all-in-one ssr binary..
... that doesn't work?!? spent hours getting this to compile, it munched 20GB like it was nothing, took its damn time just to then crash while running because "cannot access imported statics on non-wasm targets" ?!?!!?? no clue, also not super sold on this SSR thing because it adds so much complexity, will probably leave this branch up here for future reference in case i want to try this again, and go back to trunk + include! static assets and full CSR for leptos
This commit is contained in:
parent
5bbdb890c8
commit
b7cc5e79b3
15 changed files with 122 additions and 158 deletions
2
.tci
2
.tci
|
@ -12,7 +12,7 @@ echo "restarting service"
|
|||
systemctl --user start upub
|
||||
echo "rebuilding frontend"
|
||||
cd web
|
||||
CARGO_BUILD_JOBS=4 /opt/bin/trunk build --release --public-url 'https://dev.upub.social/web'
|
||||
CARGO_BUILD_JOBS=4 /opt/bin/trunk build --profile=wasm-release --public-url 'https://dev.upub.social/web'
|
||||
echo "deploying frontend"
|
||||
rm /srv/http/upub/dev/web/*
|
||||
mv ./dist/* /srv/http/upub/dev/web/
|
||||
|
|
72
Cargo.lock
generated
72
Cargo.lock
generated
|
@ -270,44 +270,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core 0.4.5",
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.2.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"itoa",
|
||||
"matchit 0.7.3",
|
||||
"memchr",
|
||||
"mime",
|
||||
"multer",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"sync_wrapper",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8"
|
||||
dependencies = [
|
||||
"axum-core 0.5.0",
|
||||
"bytes",
|
||||
"form_urlencoded",
|
||||
"futures-util",
|
||||
"http 1.2.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"itoa",
|
||||
"matchit 0.8.4",
|
||||
"matchit",
|
||||
"memchr",
|
||||
"mime",
|
||||
"multer",
|
||||
|
@ -344,25 +316,6 @@ dependencies = [
|
|||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http 1.2.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -1710,7 +1663,7 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|||
name = "httpsign"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum 0.8.1",
|
||||
"axum",
|
||||
"base64",
|
||||
"openssl",
|
||||
"thiserror 2.0.11",
|
||||
|
@ -2137,7 +2090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "43b613d5784037baee42a11d21bc263adfc1a55e416556a3d5bfe39c7b87fadf"
|
||||
dependencies = [
|
||||
"any_spawner",
|
||||
"axum 0.7.9",
|
||||
"axum",
|
||||
"dashmap",
|
||||
"futures",
|
||||
"hydration_context",
|
||||
|
@ -2452,12 +2405,6 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.10.6"
|
||||
|
@ -3881,7 +3828,7 @@ version = "0.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5dd7fcccd3ef2081da086c1f8595b506627abbbbc9f64be0141d2251219570e"
|
||||
dependencies = [
|
||||
"axum 0.7.9",
|
||||
"axum",
|
||||
"bytes",
|
||||
"const_format",
|
||||
"dashmap",
|
||||
|
@ -5124,11 +5071,13 @@ dependencies = [
|
|||
"apb",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64",
|
||||
"chrono",
|
||||
"hmac",
|
||||
"httpsign",
|
||||
"jrd",
|
||||
"leptos_config",
|
||||
"mdhtml",
|
||||
"nodeinfo",
|
||||
"openssl",
|
||||
|
@ -5197,14 +5146,12 @@ name = "upub-routes"
|
|||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"apb",
|
||||
"axum 0.8.1",
|
||||
"axum",
|
||||
"chrono",
|
||||
"httpsign",
|
||||
"jrd",
|
||||
"leptos",
|
||||
"leptos_axum",
|
||||
"leptos_meta",
|
||||
"leptos_router",
|
||||
"leptos_config",
|
||||
"mastodon-async-entities",
|
||||
"nodeinfo",
|
||||
"rand",
|
||||
|
@ -5219,6 +5166,7 @@ dependencies = [
|
|||
"tower-http",
|
||||
"tracing",
|
||||
"upub",
|
||||
"upub-web",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
12
Cargo.toml
12
Cargo.toml
|
@ -24,7 +24,7 @@ repository = "https://git.alemi.dev/upub.git"
|
|||
readme = "README.md"
|
||||
|
||||
[[bin]]
|
||||
name = "upub"
|
||||
name = "upub-bin"
|
||||
path = "main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
@ -50,8 +50,14 @@ serve = ["dep:upub-routes"]
|
|||
migrate = ["dep:upub-migrations"]
|
||||
cli = ["dep:upub-cli"]
|
||||
worker = ["dep:upub-worker"]
|
||||
web = []
|
||||
web-build-fe = []
|
||||
web = ["upub/web", "upub-routes?/web"]
|
||||
|
||||
[[workspace.metadata.leptos]]
|
||||
name = "upub"
|
||||
bin-package = "upub-bin"
|
||||
bin-features = ["serve", "migrate", "cli", "worker", "web"]
|
||||
lib-package = "upub-web"
|
||||
lib-features = ["leptos-hydrate"]
|
||||
|
||||
[profile.wasm-release]
|
||||
inherits = "release"
|
||||
|
|
12
build.rs
12
build.rs
|
@ -1,12 +0,0 @@
|
|||
fn main() {
|
||||
#[cfg(all(feature = "web", feature = "web-build-fe"))]
|
||||
{
|
||||
println!("cargo:warning=running sub-process to build frontend");
|
||||
let status = std::process::Command::new("cargo")
|
||||
.current_dir("web")
|
||||
.args(["build", "--profile=wasm-release", "--target=wasm32-unknown-unknown"])
|
||||
.status()
|
||||
.unwrap();
|
||||
assert!(status.success(), "failed building wasm bundle");
|
||||
}
|
||||
}
|
|
@ -36,3 +36,9 @@ reqwest = { version = "0.12", features = ["json"] }
|
|||
apb = { path = "../apb", features = ["unstructured", "orm", "did-core", "activitypub-miscellaneous-terms", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot"] }
|
||||
# nodeinfo = "0.0.2" # the version on crates.io doesn't re-export necessary types to build the struct!!!
|
||||
nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "e865094804" }
|
||||
leptos_config = { version = "0.7", optional = true }
|
||||
axum = { version = "0.7", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
web = ["dep:leptos_config", "dep:axum"]
|
||||
|
|
|
@ -193,3 +193,30 @@ pub enum Internal {
|
|||
Activity(i64),
|
||||
Actor(i64),
|
||||
}
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
mod leptos_state {
|
||||
impl axum::extract::FromRef<super::Context> for leptos_config::LeptosOptions {
|
||||
fn from_ref(_ctx: &super::Context) -> leptos_config::LeptosOptions {
|
||||
static CONF: std::sync::OnceLock<leptos_config::LeptosOptions> = std::sync::OnceLock::new();
|
||||
CONF.get_or_init(||
|
||||
leptos_config::LeptosOptions {
|
||||
env: {
|
||||
#[cfg(debug_assertions)]{ leptos_config::Env::DEV }
|
||||
#[cfg(not(debug_assertions))] { leptos_config::Env::PROD }
|
||||
},
|
||||
output_name: "upub_web".into(),
|
||||
site_root: "web/dist".into(),
|
||||
site_pkg_dir: "pkg".into(),
|
||||
site_addr: "127.0.0.1:3000/web".parse().expect("could not create socket addr"), // TODO we don't want to serve? what is this for??
|
||||
reload_port: 3001,
|
||||
reload_external_port: None,
|
||||
reload_ws_protocol: leptos_config::ReloadWSProtocol::WS,
|
||||
not_found_path: "web/404.html".into(),
|
||||
hash_file: "hash.txt".into(),
|
||||
hash_files: true,
|
||||
}
|
||||
).clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ jrd = "0.1"
|
|||
tracing = "0.1"
|
||||
tokio = "1.43"
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
axum = { version = "0.8", features = ["multipart"] }
|
||||
axum = { version = "0.7", features = ["multipart"] }
|
||||
tower-http = { version = "0.6", features = ["cors", "trace"] }
|
||||
httpsign = { path = "../utils/httpsign/", features = ["axum"] }
|
||||
apb = { path = "../apb", features = ["unstructured", "orm", "activitypub-fe", "activitypub-counters", "litepub", "ostatus", "toot", "jsonld"] }
|
||||
|
@ -33,18 +33,12 @@ nodeinfo = { git = "https://codeberg.org/thefederationinfo/nodeinfo-rs", rev = "
|
|||
mastodon-async-entities = { version = "1.1.0", optional = true }
|
||||
time = { version = "0.3", features = ["serde"], optional = true }
|
||||
# frontend
|
||||
leptos = { version = "0.7", optional = true }
|
||||
leptos_router = { version = "0.7", optional = true }
|
||||
leptos_axum = { version = "0.7", optional = true }
|
||||
leptos_meta = { version = "0.7", optional = true }
|
||||
leptos_config = { version = "0.7", optional = true }
|
||||
upub-web = { path = "../web", default-features = false, optional = true }
|
||||
|
||||
[features]
|
||||
default = ["activitypub", "web"]
|
||||
default = ["activitypub"]
|
||||
activitypub = []
|
||||
mastodon = ["dep:mastodon-async-entities"]
|
||||
web = [
|
||||
"dep:leptos",
|
||||
"dep:leptos_router",
|
||||
"dep:leptos_axum",
|
||||
"dep:leptos_meta"
|
||||
]
|
||||
web = ["dep:leptos_axum", "dep:leptos_config", "dep:upub-web", "upub-web?/leptos-ssr", "upub/web"]
|
||||
|
|
|
@ -22,7 +22,7 @@ impl super::ActivityPubRouter for Router<upub::Context> {
|
|||
// fetch route, to debug and retreive remote objects
|
||||
.route("/search", get(ap::application::search))
|
||||
.route("/fetch", get(ap::application::ap_fetch))
|
||||
.route("/proxy/{hmac}/{uri}", get(ap::application::cloak_proxy))
|
||||
.route("/proxy/:hmac/:uri", get(ap::application::cloak_proxy))
|
||||
.route("/inbox", post(ap::inbox::post))
|
||||
.route("/inbox", get(ap::inbox::get))
|
||||
.route("/inbox/page", get(ap::inbox::page))
|
||||
|
@ -39,49 +39,49 @@ impl super::ActivityPubRouter for Router<upub::Context> {
|
|||
.route("/.well-known/host-meta", get(ap::well_known::host_meta))
|
||||
.route("/.well-known/nodeinfo", get(ap::well_known::nodeinfo_discovery))
|
||||
.route("/.well-known/oauth-authorization-server", get(ap::well_known::oauth_authorization_server))
|
||||
.route("/nodeinfo/{version}", get(ap::well_known::nodeinfo))
|
||||
.route("/nodeinfo/:version", get(ap::well_known::nodeinfo))
|
||||
// actor routes
|
||||
.route("/actors/{id}", get(ap::actor::view))
|
||||
.route("/actors/{id}/inbox", post(ap::actor::inbox::post))
|
||||
.route("/actors/{id}/inbox", get(ap::actor::inbox::get))
|
||||
.route("/actors/{id}/inbox/page", get(ap::actor::inbox::page))
|
||||
.route("/actors/{id}/outbox", post(ap::actor::outbox::post))
|
||||
.route("/actors/{id}/outbox", get(ap::actor::outbox::get))
|
||||
.route("/actors/{id}/outbox/page", get(ap::actor::outbox::page))
|
||||
.route("/actors/{id}/notifications", get(ap::actor::notifications::get))
|
||||
.route("/actors/{id}/notifications/page", get(ap::actor::notifications::page))
|
||||
.route("/actors/{id}/followers", get(ap::actor::following::get::<false>))
|
||||
.route("/actors/{id}/followers/page", get(ap::actor::following::page::<false>))
|
||||
.route("/actors/{id}/following", get(ap::actor::following::get::<true>))
|
||||
.route("/actors/{id}/following/page", get(ap::actor::following::page::<true>))
|
||||
.route("/actors/{id}/likes", get(ap::actor::likes::get))
|
||||
.route("/actors/{id}/likes/page", get(ap::actor::likes::page))
|
||||
.route("/actors/:id", get(ap::actor::view))
|
||||
.route("/actors/:id/inbox", post(ap::actor::inbox::post))
|
||||
.route("/actors/:id/inbox", get(ap::actor::inbox::get))
|
||||
.route("/actors/:id/inbox/page", get(ap::actor::inbox::page))
|
||||
.route("/actors/:id/outbox", post(ap::actor::outbox::post))
|
||||
.route("/actors/:id/outbox", get(ap::actor::outbox::get))
|
||||
.route("/actors/:id/outbox/page", get(ap::actor::outbox::page))
|
||||
.route("/actors/:id/notifications", get(ap::actor::notifications::get))
|
||||
.route("/actors/:id/notifications/page", get(ap::actor::notifications::page))
|
||||
.route("/actors/:id/followers", get(ap::actor::following::get::<false>))
|
||||
.route("/actors/:id/followers/page", get(ap::actor::following::page::<false>))
|
||||
.route("/actors/:id/following", get(ap::actor::following::get::<true>))
|
||||
.route("/actors/:id/following/page", get(ap::actor::following::page::<true>))
|
||||
.route("/actors/:id/likes", get(ap::actor::likes::get))
|
||||
.route("/actors/:id/likes/page", get(ap::actor::likes::page))
|
||||
.route("/groups", get(ap::groups::get))
|
||||
.route("/groups/page", get(ap::groups::page))
|
||||
// .route("/actors/{id}/audience", get(ap::actor::audience::get))
|
||||
// .route("/actors/{id}/audience/page", get(ap::actor::audience::page))
|
||||
// .route("/actors/:id/audience", get(ap::actor::audience::get))
|
||||
// .route("/actors/:id/audience/page", get(ap::actor::audience::page))
|
||||
// activities
|
||||
.route("/activities/{id}", get(ap::activity::view))
|
||||
.route("/activities/:id", get(ap::activity::view))
|
||||
// hashtags
|
||||
.route("/tags/{id}", get(ap::tags::get))
|
||||
.route("/tags/{id}/page", get(ap::tags::page))
|
||||
.route("/tags/:id", get(ap::tags::get))
|
||||
.route("/tags/:id/page", get(ap::tags::page))
|
||||
// specific object routes
|
||||
.route("/objects/{id}", get(ap::object::view))
|
||||
.route("/objects/{id}/replies", get(ap::object::replies::get))
|
||||
.route("/objects/{id}/replies/page", get(ap::object::replies::page))
|
||||
.route("/objects/{id}/context", get(ap::object::context::get))
|
||||
.route("/objects/{id}/context/page", get(ap::object::context::page))
|
||||
.route("/objects/{id}/likes", get(ap::object::likes::get))
|
||||
.route("/objects/{id}/likes/page", get(ap::object::likes::page))
|
||||
.route("/objects/{id}/shares", get(ap::object::shares::get))
|
||||
.route("/objects/{id}/shares/page", get(ap::object::shares::page))
|
||||
.route("/objects/:id", get(ap::object::view))
|
||||
.route("/objects/:id/replies", get(ap::object::replies::get))
|
||||
.route("/objects/:id/replies/page", get(ap::object::replies::page))
|
||||
.route("/objects/:id/context", get(ap::object::context::get))
|
||||
.route("/objects/:id/context/page", get(ap::object::context::page))
|
||||
.route("/objects/:id/likes", get(ap::object::likes::get))
|
||||
.route("/objects/:id/likes/page", get(ap::object::likes::page))
|
||||
.route("/objects/:id/shares", get(ap::object::shares::get))
|
||||
.route("/objects/:id/shares/page", get(ap::object::shares::page))
|
||||
// file routes
|
||||
.route("/file", post(ap::file::upload))
|
||||
.route("/file/{id}", get(ap::file::download))
|
||||
//.route("/objects/{id}/likes", get(ap::object::likes::get))
|
||||
//.route("/objects/{id}/likes/page", get(ap::object::likes::page))
|
||||
//.route("/objects/{id}/shares", get(ap::object::announces::get))
|
||||
//.route("/objects/{id}/shares/page", get(ap::object::announces::page))
|
||||
.route("/file/:id", get(ap::file::download))
|
||||
//.route("/objects/:id/likes", get(ap::object::likes::get))
|
||||
//.route("/objects/:id/likes/page", get(ap::object::likes::page))
|
||||
//.route("/objects/:id/shares", get(ap::object::announces::get))
|
||||
//.route("/objects/:id/shares/page", get(ap::object::announces::page))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ impl Identity {
|
|||
|
||||
pub struct AuthIdentity(pub Identity);
|
||||
|
||||
#[axum::async_trait]
|
||||
impl<S> FromRequestParts<S> for AuthIdentity
|
||||
where
|
||||
upub::Context: FromRef<S>,
|
||||
|
|
|
@ -32,7 +32,7 @@ pub mod mastodon { impl super::MastodonRouter for axum::Router<upub::Context> {}
|
|||
|
||||
|
||||
pub trait WebRouter {
|
||||
fn web_routes(self) -> Self where Self: Sized { self }
|
||||
fn web_routes(self, _ctx: &upub::Context) -> Self where Self: Sized { self }
|
||||
}
|
||||
|
||||
#[cfg(feature = "web")]
|
||||
|
@ -43,7 +43,6 @@ pub mod web {
|
|||
impl super::WebRouter for axum::Router<upub::Context> {}
|
||||
}
|
||||
|
||||
|
||||
pub async fn serve(ctx: upub::Context, bind: String, shutdown: impl ShutdownToken) -> Result<(), std::io::Error> {
|
||||
use tower_http::{cors::CorsLayer, trace::TraceLayer};
|
||||
|
||||
|
@ -62,8 +61,8 @@ pub async fn serve(ctx: upub::Context, bind: String, shutdown: impl ShutdownToke
|
|||
})
|
||||
)
|
||||
.ap_routes()
|
||||
.mastodon_routes() // no-op if mastodon feature is disabled
|
||||
.web_routes() // no-op if web feature is disabled
|
||||
.mastodon_routes()
|
||||
.web_routes(&ctx)
|
||||
.layer(CorsLayer::permissive())
|
||||
.with_state(ctx);
|
||||
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
use axum::{response::IntoResponse, routing::get, Router};
|
||||
|
||||
|
||||
impl super::WebRouter for Router<upub::Context> {
|
||||
fn web_routes(self) -> Self {
|
||||
self
|
||||
.route("/web/assets/upub-web.wasm", get(upub_web_wasm))
|
||||
.route("/web/assets/style.css", get(upub_style_css))
|
||||
.route("/web", get(upub_web_index))
|
||||
.route("/web/", get(upub_web_index))
|
||||
.route("/web/{*any}", get(upub_web_index))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
async fn upub_web_wasm() -> impl IntoResponse {
|
||||
include_bytes!("../../target/wasm32-unknown-unknown/wasm-release/upub-web.wasm")
|
||||
}
|
||||
|
||||
async fn upub_style_css() -> impl IntoResponse {
|
||||
include_str!("../../web/assets/style.css")
|
||||
}
|
||||
|
||||
async fn upub_web_index() -> impl IntoResponse {
|
||||
include_str!("../../web/index.html")
|
||||
}
|
11
routes/src/web/mod.rs
Normal file
11
routes/src/web/mod.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use leptos_axum::LeptosRoutes;
|
||||
|
||||
impl super::WebRouter for axum::Router<upub::Context> {
|
||||
fn web_routes(self, ctx: &upub::Context) -> Self where Self: Sized {
|
||||
self.leptos_routes(
|
||||
ctx,
|
||||
leptos_axum::generate_route_list(upub_web::App),
|
||||
move || ""
|
||||
)
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ thiserror = "2.0"
|
|||
tracing = "0.1"
|
||||
base64 = "0.22"
|
||||
openssl = "0.10" # TODO handle pubkeys with a smaller crate
|
||||
axum = { version = "0.8", optional = true }
|
||||
axum = { version = "0.7", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
|
|
@ -9,6 +9,9 @@ keywords = ["activitypub", "upub", "json", "web", "wasm"]
|
|||
repository = "https://git.alemi.dev/upub.git"
|
||||
#readme = "README.md"
|
||||
|
||||
[lib]
|
||||
crate-type = ["rlib", "cdylib"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
@ -24,7 +27,7 @@ serde_json = "1.0"
|
|||
serde_default = "0.2"
|
||||
serde-inline-default = "0.2"
|
||||
dashmap = "6.1"
|
||||
leptos = { version = "0.7", features = ["csr", "tracing"] }
|
||||
leptos = { version = "0.7", features = ["tracing"] }
|
||||
leptos_router = { version = "0.7", features = ["tracing"] }
|
||||
leptos-use = "0.15"
|
||||
codee = { version = "0.2", features = ["json_serde"] } # WHYYY LEPTOS-USE AKSJFOASHGOAEG
|
||||
|
@ -38,3 +41,9 @@ jrd = "0.1"
|
|||
tld = "2.36"
|
||||
web-sys = { version = "0.3", features = ["Screen"] }
|
||||
regex = "1.11"
|
||||
|
||||
[features]
|
||||
default = ["leptos-csr"]
|
||||
leptos-ssr = ["leptos/ssr"]
|
||||
leptos-csr = ["leptos/csr"]
|
||||
leptos-hydrate = ["leptos/hydrate"]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![recursion_limit = "256"] // oh nooo leptos...
|
||||
|
||||
mod auth;
|
||||
mod app;
|
||||
mod components;
|
||||
|
|
Loading…
Add table
Reference in a new issue