use lattice_inference::{BertModel, BertPooling};
use wasm_bindgen::prelude::*;
#[wasm_bindgen(js_name = initPanicHook)]
pub fn init_panic_hook() {
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
pub struct LatticeEmbedder {
model: BertModel,
}
#[wasm_bindgen]
impl LatticeEmbedder {
#[wasm_bindgen(constructor)]
pub fn new(
model_bytes: &[u8],
config_bytes: &[u8],
tokenizer_bytes: &[u8],
) -> Result<LatticeEmbedder, JsValue> {
let config_json = std::str::from_utf8(config_bytes)
.map_err(|e| JsValue::from_str(&format!("config.json is not valid UTF-8: {e}")))?;
let tokenizer_json = std::str::from_utf8(tokenizer_bytes)
.map_err(|e| JsValue::from_str(&format!("tokenizer.json is not valid UTF-8: {e}")))?;
let model = BertModel::from_bytes(model_bytes.to_vec(), config_json, tokenizer_json)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(LatticeEmbedder { model })
}
#[wasm_bindgen(js_name = useClsPooling)]
pub fn use_cls_pooling(&mut self) {
self.model.set_pooling(BertPooling::CLS);
}
pub fn embed(&self, text: &str) -> Result<Vec<f32>, JsValue> {
self.model
.encode(text)
.map_err(|e| JsValue::from_str(&e.to_string()))
}
#[wasm_bindgen(getter)]
pub fn dimensions(&self) -> usize {
self.model.dimensions()
}
}
#[wasm_bindgen(js_name = simdDotProduct)]
pub fn simd_dot_product(a: &[f32], b: &[f32]) -> f32 {
crate::simd::dot_product(a, b)
}
#[wasm_bindgen(js_name = simdSquaredEuclideanDistance)]
pub fn simd_squared_euclidean_distance(a: &[f32], b: &[f32]) -> f32 {
crate::simd::squared_euclidean_distance(a, b)
}
#[wasm_bindgen(js_name = simdCosineSimilarity)]
pub fn simd_cosine_similarity(a: &[f32], b: &[f32]) -> f32 {
crate::simd::cosine_similarity(a, b)
}
#[wasm_bindgen(js_name = simdNormalize)]
pub fn simd_normalize(v: &mut [f32]) {
crate::simd::normalize(v)
}
#[wasm_bindgen(js_name = simdSimd128Dispatch)]
pub fn simd_simd128_dispatch() -> bool {
crate::simd::simd_config().simd128_enabled()
}