|
34 | 34 | mod detection; |
35 | 35 |
|
36 | 36 | use dataflow_rs::{AsyncFunctionHandler, Engine, Message, Workflow}; |
37 | | -use serde_json::{json, Value}; |
| 37 | +use serde_json::{Value, json}; |
38 | 38 | use std::collections::HashMap; |
39 | 39 | use std::sync::Arc; |
40 | 40 | use wasm_bindgen::prelude::*; |
@@ -214,34 +214,37 @@ impl ReframeEngine { |
214 | 214 |
|
215 | 215 | /// Generate a sample message. |
216 | 216 | /// |
217 | | - /// The payload is stored as a raw string containing generation parameters. |
| 217 | + /// The payload should be a JSON string containing a scenario schema with `source_type` field. |
| 218 | + /// The `source_type` is used to set `metadata.message_type` for workflow routing. |
218 | 219 | /// |
219 | 220 | /// # Arguments |
220 | | - /// * `payload` - Raw string payload with generation parameters |
| 221 | + /// * `payload` - JSON string containing the scenario schema |
221 | 222 | /// |
222 | 223 | /// # Returns |
223 | 224 | /// A Promise that resolves to the generated message as a JSON string |
224 | 225 | /// |
225 | 226 | /// # Example |
226 | 227 | /// ```javascript |
227 | | - /// const params = '{"message_type": "MT103", "scenario": "standard"}'; |
228 | | - /// const result = await engine.generate(params); |
| 228 | + /// const scenario = '{"source_type": "MT103", "schema": {...}}'; |
| 229 | + /// const result = await engine.generate(scenario); |
| 230 | + /// const output = JSON.parse(result); |
| 231 | + /// console.log(output.data.result); // Generated MT103 message |
229 | 232 | /// ``` |
230 | 233 | #[wasm_bindgen] |
231 | 234 | pub fn generate(&self, payload: &str) -> js_sys::Promise { |
232 | | - self.process_with_engine(&self.generate_engine, payload, false) |
| 235 | + self.process_generate(&self.generate_engine, payload, false) |
233 | 236 | } |
234 | 237 |
|
235 | 238 | /// Generate a sample message with execution trace. |
236 | 239 | /// |
237 | 240 | /// # Arguments |
238 | | - /// * `payload` - Raw string payload with generation parameters |
| 241 | + /// * `payload` - JSON string containing the scenario schema |
239 | 242 | /// |
240 | 243 | /// # Returns |
241 | 244 | /// A Promise that resolves to the execution trace as a JSON string |
242 | 245 | #[wasm_bindgen] |
243 | 246 | pub fn generate_with_trace(&self, payload: &str) -> js_sys::Promise { |
244 | | - self.process_with_engine(&self.generate_engine, payload, true) |
| 247 | + self.process_generate(&self.generate_engine, payload, true) |
245 | 248 | } |
246 | 249 |
|
247 | 250 | /// Validate a message. |
@@ -410,6 +413,62 @@ impl ReframeEngine { |
410 | 413 | }) |
411 | 414 | } |
412 | 415 | } |
| 416 | + |
| 417 | + /// Internal helper to process a generate request. |
| 418 | + /// Parses the scenario to extract source_type and sets it as metadata.message_type. |
| 419 | + fn process_generate( |
| 420 | + &self, |
| 421 | + engine: &Arc<Engine>, |
| 422 | + payload: &str, |
| 423 | + with_trace: bool, |
| 424 | + ) -> js_sys::Promise { |
| 425 | + // Parse the scenario to extract source_type for workflow routing |
| 426 | + let scenario: Value = match serde_json::from_str(payload) { |
| 427 | + Ok(v) => v, |
| 428 | + Err(e) => { |
| 429 | + let error_msg = format!("Invalid scenario JSON: {}", e); |
| 430 | + return future_to_promise(async move { Err(JsValue::from_str(&error_msg)) }); |
| 431 | + } |
| 432 | + }; |
| 433 | + |
| 434 | + // Extract source_type from scenario |
| 435 | + let message_type = scenario |
| 436 | + .get("source_type") |
| 437 | + .and_then(|v| v.as_str()) |
| 438 | + .unwrap_or("") |
| 439 | + .to_string(); |
| 440 | + |
| 441 | + // Create message with the scenario as payload |
| 442 | + let mut message = Message::from_value(&scenario); |
| 443 | + |
| 444 | + // Set metadata.message_type for workflow condition routing |
| 445 | + if let Some(metadata) = message.metadata_mut().as_object_mut() { |
| 446 | + metadata.insert("message_type".to_string(), json!(message_type)); |
| 447 | + } |
| 448 | + |
| 449 | + // Clone the Arc for the async block |
| 450 | + let engine = Arc::clone(engine); |
| 451 | + |
| 452 | + if with_trace { |
| 453 | + future_to_promise(async move { |
| 454 | + match engine.process_message_with_trace(&mut message).await { |
| 455 | + Ok(trace) => serde_json::to_string(&trace) |
| 456 | + .map(|s| JsValue::from_str(&s)) |
| 457 | + .map_err(|e| JsValue::from_str(&e.to_string())), |
| 458 | + Err(e) => Err(JsValue::from_str(&e.to_string())), |
| 459 | + } |
| 460 | + }) |
| 461 | + } else { |
| 462 | + future_to_promise(async move { |
| 463 | + match engine.process_message(&mut message).await { |
| 464 | + Ok(()) => serde_json::to_string(&message) |
| 465 | + .map(|s| JsValue::from_str(&s)) |
| 466 | + .map_err(|e| JsValue::from_str(&e.to_string())), |
| 467 | + Err(e) => Err(JsValue::from_str(&e.to_string())), |
| 468 | + } |
| 469 | + }) |
| 470 | + } |
| 471 | + } |
413 | 472 | } |
414 | 473 |
|
415 | 474 | /// Parse an optional workflow array value into a Vec<Workflow>. |
|
0 commit comments