From cf50b0c37bef9e69caf6224b961770dd5be4901e Mon Sep 17 00:00:00 2001
From: Arpita-Jaiswal <ayushipujaa@gmail.com>
Date: Sun, 24 Nov 2024 14:14:12 +0530
Subject: [PATCH] Added fastn_resolved_to_js::get_all_asts

---
 fastn-resolved-to-js/src/html.rs | 28 ++++++---
 fastn-resolved-to-js/src/lib.rs  | 78 +++++++++++++++++++++++++
 v0.5/fastn-compiler/src/js.rs    | 98 ++++++--------------------------
 v0.5/fastn-compiler/src/lib.rs   |  2 +-
 4 files changed, 116 insertions(+), 90 deletions(-)

diff --git a/fastn-resolved-to-js/src/html.rs b/fastn-resolved-to-js/src/html.rs
index 10b31de39..1897a481d 100644
--- a/fastn-resolved-to-js/src/html.rs
+++ b/fastn-resolved-to-js/src/html.rs
@@ -1,18 +1,26 @@
 use fastn_resolved_to_js::extensions::*;
 
 pub struct HtmlInput {
-    package: Package,
-    js: String,
-    #[expect(unused)]
-    css_files: Vec<String>,
-    #[expect(unused)]
-    js_files: Vec<String>,
-    doc: dyn fastn_resolved::tdoc::TDoc,
+    pub package: Package,
+    pub js: String,
+    pub css_files: Vec<String>,
+    pub js_files: Vec<String>,
+    pub doc: Box<dyn fastn_resolved::tdoc::TDoc>,
+    pub has_rive_component: bool,
 }
 const EMPTY_HTML_BODY: &str = "<body></body><style id=\"styles\"></style>";
 
 impl HtmlInput {
     pub fn to_html(&self) -> String {
+        let mut scripts =
+            fastn_resolved_to_js::utils::get_external_scripts(self.has_rive_component);
+        scripts.push(fastn_resolved_to_js::utils::get_js_html(
+            self.js_files.as_slice(),
+        ));
+        scripts.push(fastn_resolved_to_js::utils::get_css_html(
+            self.css_files.as_slice(),
+        ));
+
         format!(
             include_str!("../../ftd/ftd-js.html"),
             fastn_package = self.package.name,
@@ -36,11 +44,13 @@ impl HtmlInput {
                 <script src="{}"></script>
                 <script src="{}"></script>
                 <link rel="stylesheet" href="{}">
+                {}
             "#,
                 hashed_markdown_js(),
                 hashed_prism_js(),
-                hashed_default_ftd_js(self.package.name.as_str(), &self.doc),
+                hashed_default_ftd_js(self.package.name.as_str(), self.doc.as_ref()),
                 hashed_prism_css(),
+                scripts.join("").as_str()
             )
             .as_str(),
             extra_js = "", // Todo
@@ -165,12 +175,14 @@ fn default_bag_into_js_ast(doc: &dyn fastn_resolved::tdoc::TDoc) -> Vec<fastn_js
     ftd_asts
 }
 
+#[derive(Debug, Default)]
 pub struct Package {
     name: String,
     base_url: Option<String>,
     favicon: Option<Favicon>,
 }
 
+#[derive(Debug, Default)]
 pub struct Favicon {
     path: String,
     content_type: String,
diff --git a/fastn-resolved-to-js/src/lib.rs b/fastn-resolved-to-js/src/lib.rs
index d806fc540..58db572f7 100644
--- a/fastn-resolved-to-js/src/lib.rs
+++ b/fastn-resolved-to-js/src/lib.rs
@@ -341,3 +341,81 @@ pub fn default_bag_into_js_ast(doc: &dyn fastn_resolved::tdoc::TDoc) -> Vec<fast
     ftd_asts.extend(export_asts);
     ftd_asts
 }
+
+pub struct AstOutput {
+    pub ast: Vec<fastn_js::Ast>,
+    pub has_rive_components: bool,
+}
+pub fn get_all_asts<'a, T: Iterator<Item = &'a fastn_resolved::Definition>>(
+    doc: &dyn fastn_resolved::tdoc::TDoc,
+    tree: &[&fastn_resolved::ComponentInvocation],
+    used_definitions: T,
+) -> AstOutput {
+    // Check if the document tree uses Rive, if so add the Rive script.
+    let mut has_rive_components = false;
+    let mut export_asts = vec![];
+
+    let mut document_asts = vec![fastn_resolved_to_js::from_tree(
+        tree,
+        doc,
+        &mut has_rive_components,
+    )];
+
+    for definition in used_definitions {
+        if let fastn_resolved::Definition::Component(c) = definition {
+            document_asts.push(c.to_ast(doc, &mut has_rive_components));
+        } else if let fastn_resolved::Definition::Variable(v) = definition {
+            document_asts.push(v.to_ast(
+                doc,
+                Some(fastn_js::GLOBAL_VARIABLE_MAP.to_string()),
+                &mut has_rive_components,
+            ));
+        } else if let fastn_resolved::Definition::WebComponent(web_component) = definition {
+            document_asts.push(web_component.to_ast(doc));
+        } else if let fastn_resolved::Definition::Function(f) = definition {
+            document_asts.push(f.to_ast(doc));
+        } else if let fastn_resolved::Definition::Export { from, to, .. } = definition {
+            if doc.get_opt_record(from).is_some() {
+                continue;
+            }
+            export_asts.push(fastn_js::Ast::Export {
+                from: from.to_string(),
+                to: to.to_string(),
+            })
+        } else if let fastn_resolved::Definition::OrType(ot) = definition {
+            let mut fields = vec![];
+            for variant in &ot.variants {
+                if let Some(value) = &variant.clone().fields().get(0).unwrap().value {
+                    fields.push((
+                        variant
+                            .name()
+                            .trim_start_matches(
+                                format!(
+                                    "{}.",
+                                    fastn_resolved::OrType::or_type_name(ot.name.as_str())
+                                )
+                                .as_str(),
+                            )
+                            .to_string(),
+                        value.to_fastn_js_value_with_none(doc, &mut false),
+                    ));
+                }
+            }
+            document_asts.push(fastn_js::Ast::OrType(fastn_js::OrType {
+                name: ot.name.clone(),
+                variant: fastn_js::SetPropertyValue::Value(fastn_js::Value::Record {
+                    fields,
+                    other_references: vec![],
+                }),
+                prefix: Some(fastn_js::GLOBAL_VARIABLE_MAP.to_string()),
+            }));
+        }
+    }
+
+    document_asts.extend(export_asts);
+
+    AstOutput {
+        ast: document_asts,
+        has_rive_components,
+    }
+}
diff --git a/v0.5/fastn-compiler/src/js.rs b/v0.5/fastn-compiler/src/js.rs
index ca311340d..b1fa44011 100644
--- a/v0.5/fastn-compiler/src/js.rs
+++ b/v0.5/fastn-compiler/src/js.rs
@@ -1,5 +1,5 @@
 impl fastn_compiler::Compiler {
-    pub(crate) fn js(&self) -> String {
+    pub(crate) fn js(&self) -> fastn_resolved_to_js::HtmlInput {
         use fastn_resolved::tdoc::TDoc;
         use fastn_resolved_to_js::extensions::*;
 
@@ -11,91 +11,27 @@ impl fastn_compiler::Compiler {
         // every symbol in self.symbol_used in the bag must be UR::R now
         let used_definitions = self.used_definitions();
         let doc = fastn_compiler::TDoc {
-            name: "",
+            name: "", // Todo: Package name
             definitions: &used_definitions,
             builtins: fastn_builtins::builtins(),
         };
 
-        // Check if the document tree uses Rive, if so add the Rive script.
-        let mut has_rive_components = false;
-        let mut export_asts = vec![];
-
-        let mut document_asts = vec![fastn_resolved_to_js::from_tree(
-            resolved_content.as_slice(),
+        let css_files = self.external_css_files(&used_definitions);
+        let js_files = self.external_js_files(&used_definitions);
+        let output = fastn_resolved_to_js::get_all_asts(
             &doc,
-            &mut has_rive_components,
-        )];
-
-        for definition in used_definitions.values() {
-            if let fastn_resolved::Definition::Component(c) = definition {
-                document_asts.push(c.to_ast(&doc, &mut has_rive_components));
-            } else if let fastn_resolved::Definition::Variable(v) = definition {
-                document_asts.push(v.to_ast(
-                    &doc,
-                    Some(fastn_js::GLOBAL_VARIABLE_MAP.to_string()),
-                    &mut has_rive_components,
-                ));
-            } else if let fastn_resolved::Definition::WebComponent(web_component) = definition {
-                document_asts.push(web_component.to_ast(&doc));
-            } else if let fastn_resolved::Definition::Function(f) = definition {
-                document_asts.push(f.to_ast(&doc));
-            } else if let fastn_resolved::Definition::Export { from, to, .. } = definition {
-                if doc.get_opt_record(from).is_some() {
-                    continue;
-                }
-                export_asts.push(fastn_js::Ast::Export {
-                    from: from.to_string(),
-                    to: to.to_string(),
-                })
-            } else if let fastn_resolved::Definition::OrType(ot) = definition {
-                let mut fields = vec![];
-                for variant in &ot.variants {
-                    if let Some(value) = &variant.clone().fields().get(0).unwrap().value {
-                        fields.push((
-                            variant
-                                .name()
-                                .trim_start_matches(
-                                    format!(
-                                        "{}.",
-                                        fastn_resolved::OrType::or_type_name(ot.name.as_str())
-                                    )
-                                    .as_str(),
-                                )
-                                .to_string(),
-                            value.to_fastn_js_value_with_none(&doc, &mut false),
-                        ));
-                    }
-                }
-                document_asts.push(fastn_js::Ast::OrType(fastn_js::OrType {
-                    name: ot.name.clone(),
-                    variant: fastn_js::SetPropertyValue::Value(fastn_js::Value::Record {
-                        fields,
-                        other_references: vec![],
-                    }),
-                    prefix: Some(fastn_js::GLOBAL_VARIABLE_MAP.to_string()),
-                }));
-            }
+            resolved_content.as_slice(),
+            used_definitions.into_iter().map(|(_, v)| v),
+        );
+        let js = fastn_js::to_js(output.ast.as_slice(), "");
+
+        fastn_resolved_to_js::HtmlInput {
+            package: Default::default(), // Todo
+            js,
+            css_files,
+            js_files,
+            doc: Box::new(doc),
+            has_rive_component: output.has_rive_components,
         }
-
-        document_asts.extend(export_asts);
-
-        let mut scripts = fastn_resolved_to_js::utils::get_external_scripts(has_rive_components);
-        scripts.push(fastn_resolved_to_js::utils::get_js_html(
-            self.external_js_files(&used_definitions).as_slice(),
-        ));
-        scripts.push(fastn_resolved_to_js::utils::get_css_html(
-            self.external_css_files(&used_definitions).as_slice(),
-        ));
-
-        let js_document_script = fastn_js::to_js(document_asts.as_slice(), "");
-
-        js_document_script
     }
 }
-
-#[expect(unused)]
-pub struct Output {
-    js: String,
-    css_files: Vec<String>,
-    js_files: Vec<String>,
-}
diff --git a/v0.5/fastn-compiler/src/lib.rs b/v0.5/fastn-compiler/src/lib.rs
index ffeeb2663..f1aa38771 100644
--- a/v0.5/fastn-compiler/src/lib.rs
+++ b/v0.5/fastn-compiler/src/lib.rs
@@ -18,7 +18,7 @@ pub use symbols::SymbolStore;
 
 pub struct Output {
     #[expect(unused)]
-    js: String,
+    js: fastn_resolved_to_js::HtmlInput,
     #[expect(unused)]
     warnings: Vec<fastn_section::Spanned<fastn_section::Warning>>,
     #[expect(unused)]