2024-07-02 21:59:30 +02:00
|
|
|
use crate::mode::{Mode, GLOBAL_MODE};
|
2024-10-12 12:45:23 +02:00
|
|
|
use ssr_rs::{Ssr, SsrError};
|
2024-05-18 20:45:35 +02:00
|
|
|
use std::cell::RefCell;
|
|
|
|
|
use std::fs::read_to_string;
|
2024-06-23 20:15:33 +02:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
2024-07-07 11:44:36 +02:00
|
|
|
/// For the server side rendering we need to split the implementation between dev and prod.
|
|
|
|
|
/// This completely remove the multi-thread optimization on dev but allow the dev server to
|
|
|
|
|
/// update the SSR result without reloading the whole server.
|
|
|
|
|
pub struct Js;
|
|
|
|
|
|
2024-11-26 21:37:00 +01:00
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
|
const PROD_BUNDLE_PATH: &str = ".\\out\\server\\prod-server.js";
|
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
|
const DEV_BUNDLE_PATH: &str = ".\\.tuono\\server\\dev-server.js";
|
|
|
|
|
|
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
|
const PROD_BUNDLE_PATH: &str = "./out/server/prod-server.js";
|
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
|
const DEV_BUNDLE_PATH: &str = "./.tuono/server/dev-server.js";
|
|
|
|
|
|
2024-07-07 11:44:36 +02:00
|
|
|
impl Js {
|
2024-10-12 12:45:23 +02:00
|
|
|
pub fn render_to_string(payload: Option<&str>) -> Result<String, SsrError> {
|
2024-07-07 11:44:36 +02:00
|
|
|
let mode = GLOBAL_MODE.get().expect("Failed to get GLOBAL_MODE");
|
|
|
|
|
|
|
|
|
|
if *mode == Mode::Dev {
|
|
|
|
|
DevJs::render_to_string(payload)
|
|
|
|
|
} else {
|
|
|
|
|
ProdJs::SSR.with(|ssr| ssr.borrow_mut().render_to_string(payload))
|
2024-06-23 20:15:33 +02:00
|
|
|
}
|
2024-07-07 11:44:36 +02:00
|
|
|
}
|
2024-06-23 20:15:33 +02:00
|
|
|
}
|
2024-05-18 20:45:35 +02:00
|
|
|
|
2024-07-07 11:44:36 +02:00
|
|
|
struct ProdJs;
|
2024-05-23 22:32:43 +02:00
|
|
|
|
2024-07-07 11:44:36 +02:00
|
|
|
impl ProdJs {
|
2024-05-18 20:45:35 +02:00
|
|
|
thread_local! {
|
|
|
|
|
pub static SSR: RefCell<Ssr<'static, 'static>> = RefCell::new(
|
2025-03-09 11:32:05 +01:00
|
|
|
Ssr::from(
|
|
|
|
|
read_to_string(PathBuf::from(PROD_BUNDLE_PATH)).expect("Server bundle not found"), ""
|
|
|
|
|
).unwrap()
|
|
|
|
|
)
|
2024-05-18 20:45:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
2024-07-07 11:44:36 +02:00
|
|
|
|
|
|
|
|
struct DevJs;
|
|
|
|
|
|
|
|
|
|
impl DevJs {
|
2024-10-12 12:45:23 +02:00
|
|
|
pub fn render_to_string(params: Option<&str>) -> Result<String, SsrError> {
|
2025-03-09 11:32:05 +01:00
|
|
|
let bundle_path = read_to_string(PathBuf::from(DEV_BUNDLE_PATH));
|
|
|
|
|
|
|
|
|
|
if let Ok(source) = bundle_path {
|
|
|
|
|
let ssr = Ssr::from(source, "");
|
|
|
|
|
if let Ok(mut ssr) = ssr {
|
|
|
|
|
ssr.render_to_string(params)
|
|
|
|
|
} else {
|
|
|
|
|
let fallback_html = read_to_string(PathBuf::from("./.tuono/index.html"))
|
|
|
|
|
.unwrap_or("Fallback HTML not loaded".to_string());
|
|
|
|
|
Ok(fallback_html.replace("[SERVER_PAYLOAD]", params.unwrap_or("")))
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
let fallback_html = read_to_string(PathBuf::from("./.tuono/index.html"))
|
|
|
|
|
.unwrap_or("Fallback HTML not loaded".to_string());
|
|
|
|
|
|
|
|
|
|
Ok(fallback_html.replace("[SERVER_PAYLOAD]", params.unwrap_or("")))
|
|
|
|
|
}
|
2024-07-07 11:44:36 +02:00
|
|
|
}
|
|
|
|
|
}
|