1#![deny(unsafe_op_in_unsafe_fn)]
53#![warn(missing_docs)]
54
55use wasm_bindgen::prelude::*;
56use web_sys::console;
57
58pub mod array;
59pub mod error;
60pub mod fft;
61pub mod integrate;
62pub mod interpolate;
63pub mod linalg;
64pub mod optimize;
65pub mod random;
66pub mod signal;
67pub mod stats;
68pub mod utils;
69
70#[wasm_bindgen(start)]
72pub fn init() {
73 #[cfg(feature = "console_error_panic_hook")]
75 console_error_panic_hook::set_once();
76
77 log("SciRS2-WASM initialized successfully");
79}
80
81#[wasm_bindgen]
83pub fn version() -> String {
84 env!("CARGO_PKG_VERSION").to_string()
85}
86
87#[wasm_bindgen]
89pub fn log(message: &str) {
90 console::log_1(&JsValue::from_str(message));
91}
92
93#[wasm_bindgen]
95pub fn has_simd_support() -> bool {
96 #[cfg(target_feature = "simd128")]
97 {
98 true
99 }
100 #[cfg(not(target_feature = "simd128"))]
101 {
102 false
103 }
104}
105
106#[wasm_bindgen]
108pub fn capabilities() -> JsValue {
109 let caps = serde_json::json!({
110 "version": env!("CARGO_PKG_VERSION"),
111 "simd": has_simd_support(),
112 "features": {
113 "array": true,
114 "linalg": cfg!(feature = "linalg"),
115 "stats": cfg!(feature = "stats"),
116 "fft": cfg!(feature = "fft"),
117 "signal": cfg!(feature = "signal"),
118 "integrate": cfg!(feature = "integrate"),
119 "optimize": cfg!(feature = "optimize"),
120 "interpolate": cfg!(feature = "interpolate"),
121 },
122 "target": {
123 "arch": std::env::consts::ARCH,
124 "os": "wasm32",
125 "family": std::env::consts::FAMILY,
126 }
127 });
128
129 serde_wasm_bindgen::to_value(&caps).unwrap_or(JsValue::NULL)
130}
131
132#[wasm_bindgen]
134pub struct PerformanceTimer {
135 start: f64,
136 label: String,
137}
138
139#[wasm_bindgen]
140impl PerformanceTimer {
141 #[wasm_bindgen(constructor)]
143 pub fn new(label: String) -> Result<PerformanceTimer, JsValue> {
144 let start = web_sys::window()
145 .ok_or_else(|| JsValue::from_str("No window object available"))?
146 .performance()
147 .ok_or_else(|| JsValue::from_str("No performance object available"))?
148 .now();
149
150 Ok(PerformanceTimer { start, label })
151 }
152
153 pub fn elapsed(&self) -> Result<f64, JsValue> {
155 let now = web_sys::window()
156 .ok_or_else(|| JsValue::from_str("No window object available"))?
157 .performance()
158 .ok_or_else(|| JsValue::from_str("No performance object available"))?
159 .now();
160
161 Ok(now - self.start)
162 }
163
164 pub fn log_elapsed(&self) -> Result<(), JsValue> {
166 let elapsed = self.elapsed()?;
167 let message = format!("{}: {:.3}ms", self.label, elapsed);
168 console::log_1(&JsValue::from_str(&message));
169 Ok(())
170 }
171}
172
173#[wasm_bindgen]
175pub fn memory_usage() -> JsValue {
176 let info = serde_json::json!({
177 "note": "WASM memory usage should be checked via JavaScript Memory API"
178 });
179
180 serde_wasm_bindgen::to_value(&info).unwrap_or(JsValue::NULL)
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 #[test]
188 fn test_version() {
189 let v = version();
190 assert!(!v.is_empty());
191 }
192
193 #[test]
194 fn test_has_simd_support() {
195 let _simd = has_simd_support();
197 }
198}