#![deny(clippy::all)]
mod transformer;
use napi::bindgen_prelude::*;
use napi_derive::napi;
use transformer::{CoreGraphTransformer, Edge as CoreEdge, PipelineStage as CorePipelineStage};
#[napi]
pub struct GraphTransformer {
inner: CoreGraphTransformer,
}
#[napi]
impl GraphTransformer {
#[napi(constructor)]
pub fn new(_config: Option<serde_json::Value>) -> Self {
Self {
inner: CoreGraphTransformer::new(),
}
}
#[napi]
pub fn version(&self) -> String {
self.inner.version()
}
#[napi]
pub fn create_proof_gate(&mut self, dim: u32) -> Result<serde_json::Value> {
let gate = self.inner.create_proof_gate(dim);
serde_json::to_value(&gate).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn prove_dimension(&mut self, expected: u32, actual: u32) -> Result<serde_json::Value> {
let result = self
.inner
.prove_dimension(expected, actual)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn create_attestation(&self, proof_id: u32) -> Result<Vec<u8>> {
let att = self.inner.create_attestation(proof_id);
Ok(att.to_bytes())
}
#[napi]
pub fn compose_proofs(&mut self, stages: Vec<serde_json::Value>) -> Result<serde_json::Value> {
let rust_stages: Vec<CorePipelineStage> = stages
.into_iter()
.map(|v| {
serde_json::from_value(v).map_err(|e| {
Error::new(
Status::InvalidArg,
format!("Invalid stage descriptor: {}", e),
)
})
})
.collect::<Result<Vec<_>>>()?;
let result = self
.inner
.compose_proofs(&rust_stages)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn verify_attestation(&self, bytes: Vec<u8>) -> bool {
self.inner.verify_attestation(&bytes)
}
#[napi]
pub fn sublinear_attention(
&mut self,
query: Vec<f64>,
edges: Vec<Vec<u32>>,
dim: u32,
k: u32,
) -> Result<serde_json::Value> {
let result = self
.inner
.sublinear_attention(&query, &edges, dim, k)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn ppr_scores(
&mut self,
source: u32,
adjacency: Vec<Vec<u32>>,
alpha: f64,
) -> Result<Vec<f64>> {
Ok(self.inner.ppr_scores(source, &adjacency, alpha))
}
#[napi]
pub fn hamiltonian_step(
&mut self,
positions: Vec<f64>,
momenta: Vec<f64>,
dt: f64,
) -> Result<serde_json::Value> {
let result = self
.inner
.hamiltonian_step(&positions, &momenta, dt)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn hamiltonian_step_graph(
&mut self,
positions: Vec<f64>,
momenta: Vec<f64>,
edges: Vec<serde_json::Value>,
dt: f64,
) -> Result<serde_json::Value> {
let rust_edges: Vec<CoreEdge> = edges
.into_iter()
.map(|v| {
serde_json::from_value(v)
.map_err(|e| Error::new(Status::InvalidArg, format!("Invalid edge: {}", e)))
})
.collect::<Result<Vec<_>>>()?;
let result = self
.inner
.hamiltonian_step_graph(&positions, &momenta, &rust_edges, dt)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn spiking_attention(
&mut self,
spikes: Vec<f64>,
edges: Vec<Vec<u32>>,
threshold: f64,
) -> Result<Vec<f64>> {
Ok(self.inner.spiking_attention(&spikes, &edges, threshold))
}
#[napi]
pub fn hebbian_update(
&mut self,
pre: Vec<f64>,
post: Vec<f64>,
weights: Vec<f64>,
lr: f64,
) -> Result<Vec<f64>> {
Ok(self.inner.hebbian_update(&pre, &post, &weights, lr))
}
#[napi]
pub fn spiking_step(
&mut self,
features: Vec<Vec<f64>>,
adjacency: Vec<f64>,
) -> Result<serde_json::Value> {
let result = self.inner.spiking_step(&features, &adjacency, 1.0);
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn verified_step(
&mut self,
weights: Vec<f64>,
gradients: Vec<f64>,
lr: f64,
) -> Result<serde_json::Value> {
let result = self
.inner
.verified_step(&weights, &gradients, lr)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn verified_training_step(
&mut self,
features: Vec<f64>,
targets: Vec<f64>,
weights: Vec<f64>,
) -> Result<serde_json::Value> {
let result = self
.inner
.verified_training_step(&features, &targets, &weights, 0.001)
.map_err(|e| Error::new(Status::GenericFailure, format!("{}", e)))?;
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn product_manifold_distance(&self, a: Vec<f64>, b: Vec<f64>, curvatures: Vec<f64>) -> f64 {
self.inner.product_manifold_distance(&a, &b, &curvatures)
}
#[napi]
pub fn product_manifold_attention(
&mut self,
features: Vec<f64>,
edges: Vec<serde_json::Value>,
) -> Result<serde_json::Value> {
let rust_edges: Vec<CoreEdge> = edges
.into_iter()
.map(|v| {
serde_json::from_value(v)
.map_err(|e| Error::new(Status::InvalidArg, format!("Invalid edge: {}", e)))
})
.collect::<Result<Vec<_>>>()?;
let curvatures = vec![0.0, -1.0]; let result = self
.inner
.product_manifold_attention(&features, &rust_edges, &curvatures);
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn causal_attention(
&mut self,
query: Vec<f64>,
keys: Vec<Vec<f64>>,
timestamps: Vec<f64>,
) -> Result<Vec<f64>> {
Ok(self.inner.causal_attention(&query, &keys, ×tamps))
}
#[napi]
pub fn causal_attention_graph(
&mut self,
features: Vec<f64>,
timestamps: Vec<f64>,
edges: Vec<serde_json::Value>,
) -> Result<Vec<f64>> {
let rust_edges: Vec<CoreEdge> = edges
.into_iter()
.map(|v| {
serde_json::from_value(v)
.map_err(|e| Error::new(Status::InvalidArg, format!("Invalid edge: {}", e)))
})
.collect::<Result<Vec<_>>>()?;
Ok(self
.inner
.causal_attention_graph(&features, ×tamps, &rust_edges))
}
#[napi]
pub fn granger_extract(
&mut self,
attention_history: Vec<f64>,
num_nodes: u32,
num_steps: u32,
) -> Result<serde_json::Value> {
let dag = self
.inner
.granger_extract(&attention_history, num_nodes, num_steps);
serde_json::to_value(&dag).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn game_theoretic_attention(
&mut self,
features: Vec<f64>,
edges: Vec<serde_json::Value>,
) -> Result<serde_json::Value> {
let rust_edges: Vec<CoreEdge> = edges
.into_iter()
.map(|v| {
serde_json::from_value(v)
.map_err(|e| Error::new(Status::InvalidArg, format!("Invalid edge: {}", e)))
})
.collect::<Result<Vec<_>>>()?;
let result = self.inner.game_theoretic_attention(&features, &rust_edges);
serde_json::to_value(&result).map_err(|e| {
Error::new(
Status::GenericFailure,
format!("Serialization error: {}", e),
)
})
}
#[napi]
pub fn stats(&self) -> serde_json::Value {
serde_json::to_value(self.inner.stats()).unwrap_or(serde_json::Value::Null)
}
#[napi]
pub fn reset(&mut self) {
self.inner.reset();
}
}
#[napi]
pub fn version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
#[napi]
pub fn init() -> String {
"RuVector Graph Transformer Node.js bindings initialized".to_string()
}