1use wasm_bindgen::prelude::*;
6use serde::{Serialize, Deserialize};
7use std::collections::HashMap;
8
9pub use crate::cache::FastCache;
11pub use crate::processor::QueryProcessor;
12
13mod cache;
14mod processor;
15#[cfg(feature = "optimizations")]
16mod optimizations;
17
18#[wasm_bindgen(start)]
20pub fn init() {
21 #[cfg(feature = "console_error_panic_hook")]
23 console_error_panic_hook::set_once();
24}
25
26#[wasm_bindgen]
28pub struct Fact {
29 cache: FastCache,
30 processor: QueryProcessor,
31}
32
33#[wasm_bindgen]
34impl Fact {
35 #[wasm_bindgen(constructor)]
37 pub fn new() -> Self {
38 Self {
39 cache: FastCache::new(),
40 processor: QueryProcessor::new(),
41 }
42 }
43
44 #[wasm_bindgen]
46 pub fn process(&mut self, query: &str, use_cache: bool) -> String {
47 if use_cache {
48 if let Some(cached) = self.cache.get(&query.to_string()) {
49 return cached;
50 }
51 }
52
53 let result = self.processor.process(&query.to_string());
54
55 if use_cache {
56 self.cache.put(query.to_string(), result.clone());
57 }
58
59 result
60 }
61
62 #[wasm_bindgen]
64 pub fn get_cache_stats(&self) -> JsValue {
65 self.cache.get_stats()
66 }
67
68 #[wasm_bindgen]
70 pub fn clear_cache(&mut self) {
71 self.cache.clear();
72 }
73
74 #[wasm_bindgen]
76 pub fn optimize(&mut self, mode: &str) -> String {
77 match mode {
78 "aggressive" => {
79 self.cache.optimize_aggressive();
80 r#"{"optimized": true, "mode": "aggressive"}"#.to_string()
81 }
82 "memory" => {
83 self.cache.optimize_memory();
84 r#"{"optimized": true, "mode": "memory"}"#.to_string()
85 }
86 _ => {
87 self.cache.optimize();
88 r#"{"optimized": true, "mode": "standard"}"#.to_string()
89 }
90 }
91 }
92}
93
94#[derive(Serialize, Deserialize, Debug, Clone)]
96pub struct CognitiveTemplate {
97 pub id: String,
98 pub name: String,
99 pub description: String,
100 pub version: String,
101 pub pattern: TemplatePattern,
102 pub cache_ttl: Option<u64>,
103 pub priority: TemplatePriority,
104 pub tags: Vec<String>,
105 pub created_at: String,
106 pub updated_at: String,
107 pub usage_count: u64,
108 pub success_rate: f64,
109 pub metadata: HashMap<String, serde_json::Value>,
110}
111
112#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
114pub enum TemplatePriority {
115 Critical,
116 High,
117 Medium,
118 Low,
119 Background,
120}
121
122#[derive(Serialize, Deserialize, Debug, Clone)]
124pub struct TemplatePattern {
125 pub pattern_type: String,
126 pub steps: Vec<ProcessingStep>,
127 pub parallel_execution: bool,
128 pub optimization_hints: Vec<OptimizationHint>,
129 pub dependencies: Vec<String>,
130 pub expected_execution_time_ms: Option<f64>,
131 pub memory_requirements: Option<usize>,
132}
133
134#[derive(Serialize, Deserialize, Debug, Clone)]
136pub enum OptimizationHint {
137 CacheAggressive,
138 ParallelProcessing,
139 MemoryOptimized,
140 SIMDVectorized,
141 BatchProcessing,
142 StreamProcessing,
143}
144
145#[derive(Serialize, Deserialize, Debug, Clone)]
147pub struct ProcessingStep {
148 pub step_type: String,
149 pub config: HashMap<String, serde_json::Value>,
150 pub step_id: String,
151 pub depends_on: Vec<String>,
152 pub retry_policy: RetryPolicy,
153 pub timeout_ms: Option<u64>,
154 pub validation_rules: Vec<ValidationRule>,
155 pub performance_metrics: Option<StepMetrics>,
156}
157
158#[derive(Serialize, Deserialize, Debug, Clone)]
160pub struct RetryPolicy {
161 pub max_attempts: u32,
162 pub backoff_strategy: BackoffStrategy,
163 pub retry_conditions: Vec<String>,
164}
165
166#[derive(Serialize, Deserialize, Debug, Clone)]
168pub enum BackoffStrategy {
169 Linear { delay_ms: u64 },
170 Exponential { base_delay_ms: u64, max_delay_ms: u64 },
171 Fixed { delay_ms: u64 },
172}
173
174#[derive(Serialize, Deserialize, Debug, Clone)]
176pub struct ValidationRule {
177 pub rule_type: String,
178 pub condition: String,
179 pub error_message: String,
180}
181
182#[derive(Serialize, Deserialize, Debug, Clone)]
184pub struct StepMetrics {
185 pub execution_count: u64,
186 pub total_time_ms: f64,
187 pub average_time_ms: f64,
188 pub success_rate: f64,
189 pub error_count: u64,
190}
191
192#[wasm_bindgen]
194pub fn process_template(template_json: &str, context_json: &str) -> String {
195 match (
196 serde_json::from_str::<CognitiveTemplate>(template_json),
197 serde_json::from_str::<serde_json::Value>(context_json),
198 ) {
199 (Ok(template), Ok(context)) => {
200 let result = apply_template(&template, &context);
202 serde_json::to_string(&result).unwrap_or_else(|e| {
203 format!(r#"{{"error": "Serialization failed: {}"}}"#, e)
204 })
205 }
206 (Err(e1), _) => format!(r#"{{"error": "Invalid template: {}"}}"#, e1),
207 (_, Err(e2)) => format!(r#"{{"error": "Invalid context: {}"}}"#, e2),
208 }
209}
210
211fn apply_template(template: &CognitiveTemplate, context: &serde_json::Value) -> serde_json::Value {
213 let start_time = js_sys::Date::now();
214 let mut result = context.clone();
215 let mut step_results = Vec::new();
216 let mut execution_metrics = HashMap::new();
217
218 if template.pattern.parallel_execution && template.pattern.steps.len() > 1 {
220 result = process_steps_parallel(&template.pattern.steps, &result, &mut step_results);
221 } else {
222 result = process_steps_sequential(&template.pattern.steps, &result, &mut step_results);
223 }
224
225 let execution_time = js_sys::Date::now() - start_time;
226
227 for hint in &template.pattern.optimization_hints {
229 result = apply_optimization_hint(hint, &result);
230 }
231
232 execution_metrics.insert("total_execution_time_ms".to_string(), serde_json::Value::Number(
233 serde_json::Number::from_f64(execution_time).unwrap()
234 ));
235 execution_metrics.insert("steps_executed".to_string(), serde_json::Value::Number(
236 serde_json::Number::from(template.pattern.steps.len())
237 ));
238
239 serde_json::json!({
240 "template_id": template.id,
241 "template_version": template.version,
242 "result": result,
243 "step_results": step_results,
244 "execution_metrics": execution_metrics,
245 "processed_at": chrono::Utc::now().to_rfc3339(),
246 "success": true,
247 "cache_key": generate_cache_key(&template.id, context)
248 })
249}
250
251fn process_steps_parallel(
253 steps: &[ProcessingStep],
254 context: &serde_json::Value,
255 step_results: &mut Vec<serde_json::Value>
256) -> serde_json::Value {
257 let mut result = context.clone();
260
261 for step in steps {
262 let step_start = js_sys::Date::now();
263 let step_result = process_step(step, &result);
264 let step_time = js_sys::Date::now() - step_start;
265
266 step_results.push(serde_json::json!({
267 "step_id": step.step_id,
268 "execution_time_ms": step_time,
269 "result": step_result
270 }));
271
272 result = step_result;
273 }
274
275 result
276}
277
278fn process_steps_sequential(
280 steps: &[ProcessingStep],
281 context: &serde_json::Value,
282 step_results: &mut Vec<serde_json::Value>
283) -> serde_json::Value {
284 let mut result = context.clone();
285 let mut completed_steps: HashMap<String, serde_json::Value> = HashMap::new();
286
287 for step in steps {
288 if !step.depends_on.is_empty() {
290 for dep in &step.depends_on {
291 if !completed_steps.contains_key(dep) {
292 continue;
294 }
295 }
296 }
297
298 let step_start = js_sys::Date::now();
299 let step_result = process_step_with_retry(step, &result);
300 let step_time = js_sys::Date::now() - step_start;
301
302 step_results.push(serde_json::json!({
303 "step_id": step.step_id,
304 "execution_time_ms": step_time,
305 "result": step_result
306 }));
307
308 completed_steps.insert(step.step_id.clone(), step_result.clone());
309 result = step_result;
310 }
311
312 result
313}
314
315fn process_step_with_retry(step: &ProcessingStep, data: &serde_json::Value) -> serde_json::Value {
317 let mut attempt = 0;
318 let max_attempts = step.retry_policy.max_attempts;
319
320 loop {
321 attempt += 1;
322
323 if let Err(validation_error) = validate_step_input(step, data) {
325 if attempt >= max_attempts {
326 return serde_json::json!({
327 "error": "Validation failed",
328 "message": validation_error,
329 "step_id": step.step_id
330 });
331 }
332 continue;
333 }
334
335 let result = process_step(step, data);
336
337 if is_step_successful(&result) {
339 return result;
340 }
341
342 if attempt >= max_attempts {
343 return serde_json::json!({
344 "error": "Max retry attempts exceeded",
345 "step_id": step.step_id,
346 "attempts": attempt
347 });
348 }
349
350 apply_backoff(&step.retry_policy.backoff_strategy, attempt);
352 }
353}
354
355fn validate_step_input(step: &ProcessingStep, data: &serde_json::Value) -> Result<(), String> {
357 for rule in &step.validation_rules {
358 match rule.rule_type.as_str() {
359 "required_field" => {
360 if data.get(&rule.condition).is_none() {
361 return Err(rule.error_message.clone());
362 }
363 },
364 "type_check" => {
365 },
367 "range_check" => {
368 },
370 _ => {}
371 }
372 }
373 Ok(())
374}
375
376fn is_step_successful(result: &serde_json::Value) -> bool {
378 !result.get("error").is_some()
379}
380
381fn apply_backoff(strategy: &BackoffStrategy, _attempt: u32) {
383 match strategy {
386 BackoffStrategy::Linear { delay_ms: _ } => {
387 },
389 BackoffStrategy::Exponential { base_delay_ms: _, max_delay_ms: _ } => {
390 },
392 BackoffStrategy::Fixed { delay_ms: _ } => {
393 }
395 }
396}
397
398fn apply_optimization_hint(hint: &OptimizationHint, result: &serde_json::Value) -> serde_json::Value {
400 match hint {
401 OptimizationHint::CacheAggressive => {
402 let mut optimized = result.clone();
404 if let serde_json::Value::Object(ref mut map) = optimized {
405 map.insert("_cache_hint".to_string(), serde_json::Value::String("aggressive".to_string()));
406 }
407 optimized
408 },
409 OptimizationHint::MemoryOptimized => {
410 compress_result(result)
412 },
413 OptimizationHint::SIMDVectorized => {
414 vectorize_result(result)
416 },
417 _ => result.clone()
418 }
419}
420
421fn generate_cache_key(template_id: &str, context: &serde_json::Value) -> String {
423 use std::collections::hash_map::DefaultHasher;
424 use std::hash::{Hash, Hasher};
425
426 let context_str = serde_json::to_string(context).unwrap_or_default();
427 let mut hasher = DefaultHasher::new();
428 template_id.hash(&mut hasher);
429 context_str.hash(&mut hasher);
430 format!("tpl_{}_{:x}", template_id, hasher.finish())
431}
432
433fn compress_result(result: &serde_json::Value) -> serde_json::Value {
435 result.clone()
437}
438
439fn vectorize_result(result: &serde_json::Value) -> serde_json::Value {
441 result.clone()
443}
444
445fn process_step(step: &ProcessingStep, data: &serde_json::Value) -> serde_json::Value {
447 match step.step_type.as_str() {
448 "transform" => transform_data(data, &step.config),
449 "analyze" => analyze_data(data, &step.config),
450 "synthesize" => synthesize_data(data, &step.config),
451 _ => data.clone(),
452 }
453}
454
455fn transform_data(data: &serde_json::Value, config: &HashMap<String, serde_json::Value>) -> serde_json::Value {
456 let mut transformed = data.clone();
458
459 if let Some(mode) = config.get("mode").and_then(|v| v.as_str()) {
460 match mode {
461 "expand" => {
462 transformed = serde_json::json!({
464 "original": data,
465 "expanded": true,
466 "timestamp": chrono::Utc::now().to_rfc3339(),
467 });
468 }
469 "compress" => {
470 if let Some(obj) = data.as_object() {
472 let compressed: serde_json::Map<String, serde_json::Value> = obj
473 .iter()
474 .filter(|(k, _)| !k.starts_with('_'))
475 .map(|(k, v)| (k.clone(), v.clone()))
476 .collect();
477 transformed = serde_json::Value::Object(compressed);
478 }
479 }
480 _ => {}
481 }
482 }
483
484 transformed
485}
486
487fn analyze_data(data: &serde_json::Value, config: &HashMap<String, serde_json::Value>) -> serde_json::Value {
488 let depth = config.get("depth")
489 .and_then(|v| v.as_str())
490 .unwrap_or("shallow");
491
492 let analysis = match depth {
493 "deep" => {
494 serde_json::json!({
495 "data": data,
496 "analysis": {
497 "type": detect_data_type(data),
498 "complexity": calculate_complexity(data),
499 "patterns": extract_patterns(data),
500 "insights": generate_insights(data),
501 }
502 })
503 }
504 _ => {
505 serde_json::json!({
506 "data": data,
507 "analysis": {
508 "type": detect_data_type(data),
509 "summary": "Basic analysis completed",
510 }
511 })
512 }
513 };
514
515 analysis
516}
517
518fn synthesize_data(data: &serde_json::Value, config: &HashMap<String, serde_json::Value>) -> serde_json::Value {
519 let format = config.get("format")
520 .and_then(|v| v.as_str())
521 .unwrap_or("summary");
522
523 match format {
524 "insights" => {
525 serde_json::json!({
526 "insights": generate_insights(data),
527 "recommendations": generate_recommendations(data),
528 "confidence": 0.85,
529 })
530 }
531 "solution" => {
532 serde_json::json!({
533 "solution": "Optimized solution based on constraints",
534 "metrics": {
535 "efficiency": 0.92,
536 "cost": 0.78,
537 "quality": 0.88,
538 },
539 "steps": ["Step 1", "Step 2", "Step 3"],
540 })
541 }
542 _ => {
543 serde_json::json!({
544 "summary": "Processing completed successfully",
545 "key_points": extract_key_points(data),
546 })
547 }
548 }
549}
550
551fn detect_data_type(data: &serde_json::Value) -> &'static str {
554 match data {
555 serde_json::Value::Object(_) => "object",
556 serde_json::Value::Array(_) => "array",
557 serde_json::Value::String(_) => "string",
558 serde_json::Value::Number(_) => "number",
559 serde_json::Value::Bool(_) => "boolean",
560 serde_json::Value::Null => "null",
561 }
562}
563
564fn calculate_complexity(data: &serde_json::Value) -> f64 {
565 let size = serde_json::to_string(data).unwrap_or_default().len();
566 let depth = calculate_depth(data, 0);
567
568 (size as f64).log2() * (depth as f64)
569}
570
571fn calculate_depth(data: &serde_json::Value, current: usize) -> usize {
572 match data {
573 serde_json::Value::Object(map) => {
574 map.values()
575 .map(|v| calculate_depth(v, current + 1))
576 .max()
577 .unwrap_or(current + 1)
578 }
579 serde_json::Value::Array(arr) => {
580 arr.iter()
581 .map(|v| calculate_depth(v, current + 1))
582 .max()
583 .unwrap_or(current + 1)
584 }
585 _ => current,
586 }
587}
588
589fn extract_patterns(data: &serde_json::Value) -> Vec<String> {
590 let mut patterns = Vec::new();
591
592 if let serde_json::Value::Object(map) = data {
593 if map.contains_key("query") || map.contains_key("question") {
594 patterns.push("inquiry".to_string());
595 }
596 if map.contains_key("data") || map.contains_key("dataset") {
597 patterns.push("analysis".to_string());
598 }
599 if map.contains_key("goal") || map.contains_key("objective") {
600 patterns.push("planning".to_string());
601 }
602 }
603
604 patterns
605}
606
607fn generate_insights(_data: &serde_json::Value) -> Vec<String> {
608 vec![
609 "Pattern detected in data structure".to_string(),
610 "Optimization opportunity identified".to_string(),
611 "Potential for parallel processing".to_string(),
612 ]
613}
614
615fn generate_recommendations(_data: &serde_json::Value) -> Vec<String> {
616 vec![
617 "Consider caching for improved performance".to_string(),
618 "Implement batch processing for large datasets".to_string(),
619 "Use template specialization for common patterns".to_string(),
620 ]
621}
622
623fn extract_key_points(data: &serde_json::Value) -> Vec<String> {
624 vec![
625 format!("Data type: {}", detect_data_type(data)),
626 format!("Complexity score: {:.2}", calculate_complexity(data)),
627 "Processing completed successfully".to_string(),
628 ]
629}
630
631mod chrono {
633 pub struct Utc;
634
635 impl Utc {
636 pub fn now() -> DateTime {
637 DateTime
638 }
639 }
640
641 pub struct DateTime;
642
643 impl DateTime {
644 pub fn to_rfc3339(&self) -> String {
645 "2024-01-01T00:00:00Z".to_string()
646 }
647 }
648}
649
650#[cfg(test)]
651mod tests {
652 use super::*;
653
654 #[test]
655 fn test_fact_creation() {
656 let fact = Fact::new();
657 let stats = fact.get_cache_stats();
658 assert!(!stats.is_null());
659 }
660
661 #[test]
662 fn test_template_processing() {
663 let template = CognitiveTemplate {
664 id: "test".to_string(),
665 name: "Test Template".to_string(),
666 description: "Test".to_string(),
667 version: "1.0.0".to_string(),
668 pattern: TemplatePattern {
669 pattern_type: "sequential".to_string(),
670 steps: vec![],
671 parallel_execution: false,
672 optimization_hints: vec![],
673 dependencies: vec![],
674 expected_execution_time_ms: None,
675 memory_requirements: None,
676 },
677 cache_ttl: None,
678 priority: TemplatePriority::Medium,
679 tags: vec![],
680 created_at: "2024-01-01T00:00:00Z".to_string(),
681 updated_at: "2024-01-01T00:00:00Z".to_string(),
682 usage_count: 0,
683 success_rate: 1.0,
684 metadata: HashMap::new(),
685 };
686
687 let context = serde_json::json!({"test": "data"});
688 let result = apply_template(&template, &context);
689
690 assert!(result.get("template_id").is_some());
691 assert!(result.get("result").is_some());
692 }
693}