#![deny(clippy::all)]
#![warn(clippy::pedantic)]
use napi::bindgen_prelude::*;
use napi_derive::napi;
use exo_backend_classical::ClassicalBackend;
use exo_core::{Pattern, SubstrateBackend};
use std::sync::Arc;
mod types;
use types::*;
#[napi]
pub struct ExoSubstrateNode {
backend: Arc<ClassicalBackend>,
}
#[napi]
impl ExoSubstrateNode {
#[napi(constructor)]
pub fn new(dimensions: u32) -> Result<Self> {
let backend = ClassicalBackend::with_dimensions(dimensions as usize)
.map_err(|e| Error::from_reason(format!("Failed to create backend: {}", e)))?;
Ok(Self {
backend: Arc::new(backend),
})
}
#[napi(factory)]
pub fn with_dimensions(dimensions: u32) -> Result<Self> {
Self::new(dimensions)
}
#[napi]
pub fn store(&self, pattern: JsPattern) -> Result<String> {
let core_pattern: Pattern = pattern.try_into()?;
let pattern_id = core_pattern.id;
self.backend
.manifold_deform(&core_pattern, 0.0)
.map_err(|e| Error::from_reason(format!("Failed to store pattern: {}", e)))?;
Ok(pattern_id.to_string())
}
#[napi]
pub fn search(&self, embedding: Float32Array, k: u32) -> Result<Vec<JsSearchResult>> {
let results = self
.backend
.similarity_search(&embedding.to_vec(), k as usize, None)
.map_err(|e| Error::from_reason(format!("Failed to search: {}", e)))?;
Ok(results.into_iter().map(Into::into).collect())
}
#[napi]
pub fn hypergraph_query(&self, _query: String) -> Result<String> {
Ok(r#"{"NotSupported":null}"#.to_string())
}
#[napi]
pub fn dimensions(&self) -> u32 {
self.backend.dimension() as u32
}
}
#[napi]
pub fn version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
#[napi]
pub fn hello() -> String {
"Hello from EXO-AI cognitive substrate!".to_string()
}