refactor: change assets handling to vite-rs

chore: update dev environment

wip: handle vite tooling manually
This commit is contained in:
Alexander Navarro 2025-04-21 20:14:07 -04:00
parent 14a4d9b2b3
commit af709f2e72
26 changed files with 406 additions and 389 deletions

View file

@ -1,8 +1,8 @@
use axum::http::StatusCode;
use crate::config::Config;
use crate::{AppState, ResultTemplate, Tx};
use axum::{
extract::{Path, State},
http::{header, HeaderMap, HeaderValue},
response::Html,
extract::State
,
routing::get,
Router,
};
@ -11,57 +11,67 @@ use chrono::Utc;
use minijinja::context;
use serde::Serialize;
use sqlx::prelude::FromRow;
use vite_rs::ViteFile;
use tower_http::services::ServeDir;
use crate::{AppState, Error, Result, ResultTemplate, Tx};
pub fn new(config: &Config) -> Router<AppState> {
let router = Router::new()
.route("/", get(handler_home))
.nest("/public", load_asset_router(config));
pub fn new() -> Router<AppState> {
Router::new()
.route("/", get(handler_home))
.route("/assets/{*asset}", get(handle_assets))
router
}
async fn handle_assets(
State(state): State<AppState>,
Path(asset_path): Path<String>,
) -> Result<(HeaderMap, String)> {
let full_path = format!("frontend/assets/{}", asset_path);
let asset: ViteFile = state.assets.get_asset(&full_path).ok_or(Error::HTTP(StatusCode::NOT_FOUND))?;
let mut headers = HeaderMap::new();
headers.insert(header::CONTENT_TYPE, HeaderValue::from_str(&asset.content_type).unwrap());
#[cfg(feature = "embed")]
fn load_asset_router(config: &Config) -> Router<AppState> {
Router::new()
.fallback_service(
ServeDir::new(&config.public_dir),
)
.nest_service(
"/assets",
ServeDir::new(concat!(env!("OUT_DIR"), "/assets")),
)
}
Ok((headers, String::from_utf8(asset.bytes.to_vec()).unwrap()))
#[cfg(not(feature = "embed"))]
fn load_asset_router(config: &Config) -> Router<AppState> {
Router::new()
.fallback_service(
ServeDir::new(&config.public_dir),
)
.nest_service(
"/assets",
ServeDir::new(&config.public_dir.join("assets")),
)
}
#[derive(FromRow, Debug, Serialize)]
struct ExampleRow {
pub database: String,
pub version: String,
pub current_database: String,
pub current_user: String,
pub current_timestamp: chrono::DateTime<Utc>,
pub database: String,
pub version: String,
pub current_database: String,
pub current_user: String,
pub current_timestamp: chrono::DateTime<Utc>,
}
async fn handler_home(
State(state): State<AppState>,
HxRequest(hx_request): HxRequest,
mut tx: Tx,
State(state): State<AppState>,
HxRequest(hx_request): HxRequest,
mut tx: Tx,
) -> ResultTemplate {
let template = state.assets.get_template("index.html").ok_or(Error::HTTP(StatusCode::NOT_FOUND))?;
let rows = sqlx::query_as::<_, ExampleRow>("select 'Postgres' as database, setting as version, current_database(), current_user, current_timestamp from pg_settings where name = 'server_version'")
.fetch_all(&mut tx)
.await?;
let rows = sqlx::query_as::<_, ExampleRow>("select 'Postgres' as database, setting as version, current_database(), current_user, current_timestamp from pg_settings where name = 'server_version'")
.fetch_all(&mut tx)
.await?;
let content = if hx_request {
state
.assets
.render_template_block("index.html", "htmx", context!(rows => rows))?
} else {
state
.assets
.render_template("index.html", context!(rows => rows))?
};
println!("{:?}", rows);
let content = if hx_request {
template
.eval_to_state(context!(rows => rows))?
.render_block("htmx")?
} else {
template.render(context!(rows => rows))?
};
Ok(Html(content))
Ok(content)
}