use std::io::{ErrorKind, Write};
use tokio::sync::mpsc;use tracing_subscriber::{ fmt::{format::FmtSpan, MakeWriter}, EnvFilter,};use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
#[wasm_bindgen(js_name = "initializeLogger")]pub fn initialize_logger(filter: Option<String>) -> Result<(), crate::utils::Error> { let max_level = tracing::level_filters::STATIC_MAX_LEVEL .into_level() .unwrap_or(tracing::Level::ERROR);
let filter = EnvFilter::builder() .with_regex(false) .with_default_directive(max_level.into()) .parse_lossy(filter.unwrap_or_else(|| crate::DEFAULT_RUST_LOG.join(",")));
tracing_subscriber::fmt::fmt() .with_writer(ConsoleLogger::spawn()) .with_env_filter(filter) .with_span_events(FmtSpan::CLOSE) .without_time() .try_init() .map_err(|e| anyhow::anyhow!(e))?;
Ok(())}
#[derive(Debug)]struct ConsoleLogger { buffer: Vec<u8>, sender: mpsc::UnboundedSender<String>,}
impl ConsoleLogger { fn spawn() -> impl for<'w> MakeWriter<'w> + 'static { let (sender, mut receiver) = mpsc::unbounded_channel();
wasm_bindgen_futures::spawn_local(async move { while let Some(msg) = receiver.recv().await { let js_string = JsValue::from(msg); web_sys::console::log_1(&js_string); } });
move || ConsoleLogger { buffer: Vec::new(), sender: sender.clone(), } }}
impl Write for ConsoleLogger { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { self.buffer.extend(buf); Ok(buf.len()) }
fn flush(&mut self) -> std::io::Result<()> { let buffer = std::mem::take(&mut self.buffer);
let text = String::from_utf8(buffer) .map_err(|e| std::io::Error::new(ErrorKind::InvalidInput, e))?;
self.sender .send(text) .map_err(|e| std::io::Error::new(ErrorKind::BrokenPipe, e))?;
Ok(()) }}
impl Drop for ConsoleLogger { fn drop(&mut self) { if !self.buffer.is_empty() { let _ = self.flush(); } }}