1use briefcase_core::models::{DecisionSnapshot, Input, Output};
48use std::collections::HashMap;
49use wasm_bindgen::prelude::*;
50use web_sys::console;
51
52#[cfg(feature = "console_error_panic_hook")]
54#[wasm_bindgen(start)]
55pub fn main() {
56 console_error_panic_hook::set_once();
57}
58
59macro_rules! log {
61 ( $( $t:tt )* ) => {
62 console::log_1(&format!( $( $t )* ).into());
63 }
64}
65
66#[wasm_bindgen]
80pub fn init() {
81 #[cfg(feature = "console_error_panic_hook")]
82 console_error_panic_hook::set_once();
83
84 log!("🦀 Briefcase AI WASM module initialized!");
85}
86
87#[wasm_bindgen]
106pub struct JsDecisionSnapshot {
107 inner: DecisionSnapshot,
108}
109
110#[wasm_bindgen]
111impl JsDecisionSnapshot {
112 #[wasm_bindgen(constructor)]
113 pub fn new(function_name: &str) -> JsDecisionSnapshot {
114 JsDecisionSnapshot {
115 inner: DecisionSnapshot::new(function_name),
116 }
117 }
118
119 #[wasm_bindgen]
120 pub fn with_module(mut self, module_name: &str) -> JsDecisionSnapshot {
121 self.inner = self.inner.with_module(module_name);
122 self
123 }
124
125 #[wasm_bindgen]
126 pub fn add_input(
127 mut self,
128 name: &str,
129 value: &JsValue,
130 data_type: &str,
131 ) -> Result<JsDecisionSnapshot, JsError> {
132 let json_value: serde_json::Value = serde_wasm_bindgen::from_value(value.clone())
133 .map_err(|e| JsError::new(&format!("Failed to convert input value: {}", e)))?;
134
135 let input = Input::new(name, json_value, data_type);
136 self.inner = self.inner.add_input(input);
137 Ok(self)
138 }
139
140 #[wasm_bindgen]
141 pub fn add_output(
142 mut self,
143 name: &str,
144 value: &JsValue,
145 data_type: &str,
146 ) -> Result<JsDecisionSnapshot, JsError> {
147 let json_value: serde_json::Value = serde_wasm_bindgen::from_value(value.clone())
148 .map_err(|e| JsError::new(&format!("Failed to convert output value: {}", e)))?;
149
150 let output = Output::new(name, json_value, data_type);
151 self.inner = self.inner.add_output(output);
152 Ok(self)
153 }
154
155 #[wasm_bindgen]
156 pub fn add_tag(mut self, key: &str, value: &str) -> JsDecisionSnapshot {
157 self.inner = self.inner.add_tag(key, value);
158 self
159 }
160
161 #[wasm_bindgen]
162 pub fn to_json(&self) -> Result<JsValue, JsError> {
163 serde_wasm_bindgen::to_value(&self.inner)
164 .map_err(|e| JsError::new(&format!("Failed to serialize decision: {}", e)))
165 }
166}
167
168#[wasm_bindgen]
170pub struct JsMemoryStorage {
171 decisions: HashMap<String, DecisionSnapshot>,
172}
173
174impl Default for JsMemoryStorage {
175 fn default() -> Self {
176 Self::new()
177 }
178}
179
180#[wasm_bindgen]
181impl JsMemoryStorage {
182 #[wasm_bindgen(constructor)]
183 pub fn new() -> JsMemoryStorage {
184 JsMemoryStorage {
185 decisions: HashMap::new(),
186 }
187 }
188
189 #[wasm_bindgen]
190 pub fn save_decision(&mut self, decision: &JsDecisionSnapshot) -> String {
191 let id = format!("decision_{}", uuid::Uuid::new_v4());
192 self.decisions.insert(id.clone(), decision.inner.clone());
193 id
194 }
195
196 #[wasm_bindgen]
197 pub fn load_decision(&self, decision_id: &str) -> Result<JsDecisionSnapshot, JsError> {
198 let decision = self
199 .decisions
200 .get(decision_id)
201 .ok_or_else(|| JsError::new(&format!("Decision not found: {}", decision_id)))?;
202
203 Ok(JsDecisionSnapshot {
204 inner: decision.clone(),
205 })
206 }
207
208 #[wasm_bindgen]
209 pub fn health_check(&self) -> bool {
210 true
211 }
212}
213
214#[wasm_bindgen]
216pub fn version() -> String {
217 env!("CARGO_PKG_VERSION").to_string()
218}
219
220#[wasm_bindgen]
222pub fn test_functionality() -> Result<JsValue, JsError> {
223 let decision = JsDecisionSnapshot::new("test_function")
225 .with_module("test_module")
226 .add_tag("env", "test");
227
228 let mut storage = JsMemoryStorage::new();
230 let decision_id = storage.save_decision(&decision);
231 let _loaded_decision = storage.load_decision(&decision_id)?;
232
233 let result = serde_json::json!({
234 "decision_id": decision_id,
235 "storage_health": storage.health_check(),
236 "version": version(),
237 });
238
239 serde_wasm_bindgen::to_value(&result)
240 .map_err(|e| JsError::new(&format!("Failed to serialize test result: {}", e)))
241}