voce_compiler_hybrid/
lib.rs1pub mod analysis;
11pub mod bundle;
12pub mod device;
13pub mod fallback;
14
15use anyhow::Result;
16
17#[derive(Debug, Clone)]
19pub struct HybridCompileOptions {
20 pub device: device::DeviceProfile,
22 pub force_target: Option<CompileTarget>,
24}
25
26impl Default for HybridCompileOptions {
27 fn default() -> Self {
28 Self {
29 device: device::DeviceProfile::desktop(),
30 force_target: None,
31 }
32 }
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum CompileTarget {
38 Dom,
39 WebGpu,
40 Wasm,
41}
42
43#[derive(Debug)]
45pub struct HybridCompileResult {
46 pub html: String,
48 pub size_bytes: usize,
50 pub target_summary: TargetSummary,
52}
53
54#[derive(Debug, Default)]
56pub struct TargetSummary {
57 pub dom_nodes: usize,
58 pub webgpu_nodes: usize,
59 pub wasm_functions: usize,
60}
61
62pub fn compile_hybrid(json: &str, options: &HybridCompileOptions) -> Result<HybridCompileResult> {
64 let node_targets = analysis::analyze_targets(json, &options.device, options.force_target)?;
66
67 let dom_result = voce_compiler_dom::compile(
69 json,
70 &voce_compiler_dom::CompileOptions::default(),
71 )?;
72
73 let has_webgpu = node_targets.iter().any(|t| t.target == CompileTarget::WebGpu);
75 let has_wasm = node_targets.iter().any(|t| t.target == CompileTarget::Wasm);
76
77 let wasm_result = if has_wasm {
78 Some(voce_compiler_wasm::compile_to_wat(json)?)
79 } else {
80 None
81 };
82
83 let webgpu_result = if has_webgpu {
84 Some(voce_compiler_webgpu::compile_webgpu(
85 json,
86 &voce_compiler_webgpu::WebGpuCompileOptions::default(),
87 )?)
88 } else {
89 None
90 };
91
92 let html = bundle::bundle(
94 &dom_result.html,
95 webgpu_result.as_ref().map(|r| r.html.as_str()),
96 wasm_result.as_ref().map(|r| r.js_bridge.as_str()),
97 );
98
99 let size_bytes = html.len();
100
101 let target_summary = TargetSummary {
102 dom_nodes: node_targets.iter().filter(|t| t.target == CompileTarget::Dom).count(),
103 webgpu_nodes: node_targets.iter().filter(|t| t.target == CompileTarget::WebGpu).count(),
104 wasm_functions: wasm_result.as_ref().map_or(0, |r| r.function_count),
105 };
106
107 Ok(HybridCompileResult {
108 html,
109 size_bytes,
110 target_summary,
111 })
112}