use axum::{Router, routing::get};
use std::net::SocketAddr;
use tower_http::{
cors::CorsLayer,
services::{ServeDir, ServeFile},
};
pub struct WebKitConfig {
pub wasm_path: String,
pub js_path: String,
pub assets_dir: String,
pub static_dir: String,
}
impl Default for WebKitConfig {
fn default() -> Self {
Self {
wasm_path: "dist/pkg/app_bg.wasm".to_string(),
js_path: "dist/pkg/app.js".to_string(),
assets_dir: "dist/assets".to_string(),
static_dir: "dist/static".to_string(),
}
}
}
pub async fn start_server_with_config(
addr: SocketAddr,
config: WebKitConfig,
) -> Result<(), Box<dyn std::error::Error>> {
let app = Router::new()
.route("/", get(serve_shell))
.nest_service("/app.wasm", ServeFile::new(config.wasm_path))
.nest_service("/app.js", ServeFile::new(config.js_path))
.nest_service("/assets", ServeDir::new(config.assets_dir))
.nest_service("/static", ServeDir::new(config.static_dir))
.layer(CorsLayer::permissive());
log::info!("Starting WebKit preview server on http://{}", addr);
let listener = tokio::net::TcpListener::bind(addr).await?;
axum::serve(listener, app).await?;
Ok(())
}
pub async fn start_server(addr: SocketAddr) -> Result<(), Box<dyn std::error::Error>> {
start_server_with_config(addr, WebKitConfig::default()).await
}
async fn serve_shell() -> &'static str {
"<!DOCTYPE html><html><head><meta charset='utf-8'><title>CVKG Preview</title></head><body><div id='app'></div><script type='module'>import init from './app.js'; init();</script></body></html>"
}