use super::{export, render, RefGraph};
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn build_graph(ast: JsValue) -> Result<JsValue, JsValue> {
let agent: crate::AgentFile = serde_wasm_bindgen::from_value(ast)
.map_err(|e| JsValue::from_str(&format!("Failed to deserialize AST: {}", e)))?;
let graph = RefGraph::from_ast(&agent)
.map_err(|e| JsValue::from_str(&format!("Failed to build graph: {}", e)))?;
let repr = export::GraphRepr::from(&graph);
serde_wasm_bindgen::to_value(&repr)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn build_graph_from_source(source: &str) -> Result<JsValue, JsValue> {
let graph = parse_and_build(source)?;
let repr = export::GraphRepr::from(&graph);
serde_wasm_bindgen::to_value(&repr)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn validate_graph(source: &str) -> Result<JsValue, JsValue> {
let graph = parse_and_build(source)?;
let result = graph.validate();
let repr = export::ValidationResultRepr::from(&result);
serde_wasm_bindgen::to_value(&repr)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn get_graph_stats(source: &str) -> Result<JsValue, JsValue> {
let graph = parse_and_build(source)?;
let stats = graph.stats();
serde_wasm_bindgen::to_value(&stats)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn find_topic_usages(source: &str, topic_name: &str) -> Result<JsValue, JsValue> {
let graph = parse_and_build(source)?;
let topic_idx = graph
.get_topic(topic_name)
.ok_or_else(|| JsValue::from_str(&format!("Topic '{}' not found", topic_name)))?;
let usages = graph.find_usages(topic_idx);
let nodes: Vec<export::NodeRepr> = usages
.nodes
.iter()
.filter_map(|&idx| graph.get_node(idx).map(export::NodeRepr::from))
.collect();
serde_wasm_bindgen::to_value(&nodes)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn find_topic_transitions(source: &str, topic_name: &str) -> Result<JsValue, JsValue> {
let graph = parse_and_build(source)?;
let topic_idx = graph
.get_topic(topic_name)
.ok_or_else(|| JsValue::from_str(&format!("Topic '{}' not found", topic_name)))?;
let transitions = graph.find_outgoing_transitions(topic_idx);
let nodes: Vec<export::NodeRepr> = transitions
.nodes
.iter()
.filter_map(|&idx| graph.get_node(idx).map(export::NodeRepr::from))
.collect();
serde_wasm_bindgen::to_value(&nodes)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn find_variable_usages(source: &str, var_name: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
let var_idx = graph
.get_variable(var_name)
.ok_or_else(|| JsValue::from_str(&format!("Variable '{}' not found", var_name)))?;
let readers = graph.find_variable_readers(var_idx);
let writers = graph.find_variable_writers(var_idx);
let result = export::VariableUsagesRepr {
readers: readers
.nodes
.iter()
.filter_map(|&idx| graph.get_node(idx).map(export::UsageInfoRepr::from_node))
.collect(),
writers: writers
.nodes
.iter()
.filter_map(|&idx| graph.get_node(idx).map(export::UsageInfoRepr::from_node))
.collect(),
};
serde_json::to_string(&result)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn render_topic_flow(source: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
Ok(render::render_topic_flow(&graph))
}
#[wasm_bindgen]
pub fn render_graph(source: &str, view: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
match view {
"topics" => Ok(render::render_topic_flow(&graph)),
"actions" => Ok(render::render_actions_view(&graph)),
"full" => Ok(render::render_full_view(&graph)),
_ => Err(JsValue::from_str("Invalid view type. Use 'topics', 'actions', or 'full'")),
}
}
#[wasm_bindgen]
pub fn export_graph_json(source: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
let export = export::GraphExport::from_graph(&graph);
serde_json::to_string_pretty(&export)
.map_err(|e| JsValue::from_str(&format!("JSON serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn export_graph_json_compact(source: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
let repr = export::GraphRepr::from(&graph);
serde_json::to_string(&repr)
.map_err(|e| JsValue::from_str(&format!("JSON serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn export_graphml(source: &str) -> Result<String, JsValue> {
let graph = parse_and_build(source)?;
Ok(render::render_graphml(&graph))
}
#[wasm_bindgen]
pub fn extract_dependencies(source: &str) -> Result<JsValue, JsValue> {
let agent = crate::parse(source).map_err(|errs| JsValue::from_str(&errs.join("\n")))?;
let report = super::dependencies::extract_dependencies(&agent);
serde_wasm_bindgen::to_value(&report)
.map_err(|e| JsValue::from_str(&format!("Serialization error: {}", e)))
}
#[wasm_bindgen]
pub fn uses_sobject(source: &str, sobject_name: &str) -> Result<bool, JsValue> {
let agent = crate::parse(source).map_err(|errs| JsValue::from_str(&errs.join("\n")))?;
let report = super::dependencies::extract_dependencies(&agent);
Ok(report.uses_sobject(sobject_name))
}
#[wasm_bindgen]
pub fn uses_flow(source: &str, flow_name: &str) -> Result<bool, JsValue> {
let agent = crate::parse(source).map_err(|errs| JsValue::from_str(&errs.join("\n")))?;
let report = super::dependencies::extract_dependencies(&agent);
Ok(report.uses_flow(flow_name))
}
#[wasm_bindgen]
pub fn uses_apex_class(source: &str, class_name: &str) -> Result<bool, JsValue> {
let agent = crate::parse(source).map_err(|errs| JsValue::from_str(&errs.join("\n")))?;
let report = super::dependencies::extract_dependencies(&agent);
Ok(report.uses_apex_class(class_name))
}
#[wasm_bindgen]
pub fn graph_version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
fn parse_and_build(source: &str) -> Result<RefGraph, JsValue> {
let agent = crate::parse(source).map_err(|errs| JsValue::from_str(&errs.join("\n")))?;
RefGraph::from_ast(&agent)
.map_err(|e| JsValue::from_str(&format!("Failed to build graph: {}", e)))
}