use crate::error::{KreuzbergError, Result};
#[cfg(not(target_arch = "wasm32"))]
use std::{any::Any, thread};
#[cfg(target_arch = "wasm32")]
pub const MAX_HTML_SIZE_BYTES: usize = 2 * 1024 * 1024;
#[cfg(not(target_arch = "wasm32"))]
pub const LARGE_HTML_STACK_THRESHOLD_BYTES: usize = 512 * 1024;
#[cfg(not(target_arch = "wasm32"))]
pub const HTML_CONVERSION_STACK_SIZE_BYTES: usize = 16 * 1024 * 1024;
#[cfg(target_arch = "wasm32")]
pub fn check_wasm_size_limit(html: &str) -> Result<()> {
if html.len() > MAX_HTML_SIZE_BYTES {
return Err(KreuzbergError::validation(format!(
"HTML file size ({} bytes) exceeds WASM limit of {} bytes (2MB). \
Large HTML files cannot be processed in WASM due to stack constraints. \
Consider using the native library for files of this size.",
html.len(),
MAX_HTML_SIZE_BYTES
)));
}
Ok(())
}
#[cfg(not(target_arch = "wasm32"))]
pub fn check_wasm_size_limit(_html: &str) -> Result<()> {
Ok(())
}
#[cfg(not(target_arch = "wasm32"))]
pub fn html_requires_large_stack(len: usize) -> bool {
len >= LARGE_HTML_STACK_THRESHOLD_BYTES
}
#[cfg(not(target_arch = "wasm32"))]
pub fn run_on_dedicated_stack<T, F>(job: F) -> Result<T>
where
T: Send + 'static,
F: FnOnce() -> Result<T> + Send + 'static,
{
let handle = thread::Builder::new()
.name("kreuzberg-html-conversion".to_string())
.stack_size(HTML_CONVERSION_STACK_SIZE_BYTES)
.spawn(job)
.map_err(|err| KreuzbergError::Other(format!("Failed to spawn HTML conversion thread: {}", err)))?;
match handle.join() {
Ok(result) => result,
Err(panic) => {
let reason = extract_panic_reason(&panic);
Err(KreuzbergError::Other(format!("HTML conversion panicked: {}", reason)))
}
}
}
#[cfg(not(target_arch = "wasm32"))]
fn extract_panic_reason(panic: &Box<dyn Any + Send + 'static>) -> String {
if let Some(msg) = panic.downcast_ref::<&str>() {
(*msg).to_string()
} else if let Some(msg) = panic.downcast_ref::<String>() {
msg.clone()
} else {
"unknown panic".to_string()
}
}