Skip to content

Commit

Permalink
Merge pull request #5 from metacall/metassr-create
Browse files Browse the repository at this point in the history
feat: metassr-create
  • Loading branch information
giarve authored Aug 21, 2024
2 parents 03cbd14 + 7242c80 commit 80244af
Show file tree
Hide file tree
Showing 45 changed files with 1,603 additions and 29 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/target
node_modules
dist
/node_modules
/dist
.vscode
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ members = [
"crates/metassr-utils",
"crates/html-generator",
"metassr-cli",
"crates/metassr-create",
]

[[bin]]
Expand Down
2 changes: 0 additions & 2 deletions crates/metassr-build/src/scripts/hydrate.js.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,3 @@ hydrateRoot(
<App Component={Page}/>
</React.StrictMode>
);

console.log(renderToString(<App Component={Page} />))
3 changes: 1 addition & 2 deletions crates/metassr-build/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl Build for ServerSideBuilder {
Ok(t) => t,
Err(e) => return Err(anyhow!("Couldn't generate targets: {e}")),
};
dbg!(&targets.ready_for_bundling(&self.dist_path));


if let Err(e) = WebBundler::new(
&targets.ready_for_bundling(&self.dist_path),
Expand All @@ -93,7 +93,6 @@ impl Build for ServerSideBuilder {
sleep(Duration::from_secs(1));
let dist = DistDir::new(&self.dist_path)?.analyze()?;

dbg!(&dist, &self.dist_path, &self.src_path);
ManifestGenerator::new(targets.clone(), cache_dir.clone(), dist)
.generate(&head)?
.write(&self.dist_path)?;
Expand Down
78 changes: 64 additions & 14 deletions crates/metassr-build/src/server/renderer/head.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
use anyhow::{anyhow, Result};
use lazy_static::lazy_static;
use metacall::{loaders, metacall_no_arg};
use metassr_utils::cache_dir::CacheDir;
use std::{ffi::OsStr, path::PathBuf};
use std::{
collections::HashMap, ffi::OsStr, path::PathBuf, sync::Mutex, thread::sleep, time::Duration,
};

use crate::{bundler::WebBundler, traits::Exec};

lazy_static! {
static ref IS_HEAD_SCRIPT_LOADED: Mutex<HeadSciptLoadingState> =
Mutex::new(HeadSciptLoadingState::default());
}

/// A detector for if the head is loaded or not.
#[derive(Debug)]
pub struct HeadSciptLoadingState(bool);

impl HeadSciptLoadingState {
pub fn new() -> Self {
Self(false)
}
pub fn loaded(&mut self) {
self.0 = true
}
pub fn is_loaded(&self) -> bool {
self.0
}
}

impl Default for HeadSciptLoadingState {
fn default() -> Self {
Self::new()
}
}

pub struct HeadRenderer {
path: PathBuf,
cache_dir: CacheDir,
Expand All @@ -21,24 +54,41 @@ impl HeadRenderer {
pub fn render(&mut self) -> Result<String> {
let script = format!(
r#"
import Head from "{}"
import {{ renderToString }} from "react-dom/server"
import React from "react"
import Head from "{}"
import {{ renderToString }} from "react-dom/server"
import React from "react"
export function render_head() {{
return renderToString(<Head />);
}}
export function render_head() {{
return renderToString(<Head />);
}}
"#,
self.path.canonicalize()?.display()
);

let _ = self.cache_dir.insert("head.tsx", script.as_bytes())?;

// TODO(FIX): Error: Load from file handle failed, handle with name ests/web-app/dist/cache/head.tsx already loaded
let _ = loaders::from_single_file(
"ts",
format!("{}/head.tsx", self.cache_dir.dir_path().display()),
);
let path = self.cache_dir.insert("head.js", script.as_bytes())?;

if !IS_HEAD_SCRIPT_LOADED.lock().unwrap().is_loaded() {
let mut name = path.clone();
name.set_extension("");
let name = name.to_str().unwrap().to_string();

let fullpath = path.canonicalize()?.to_str().unwrap().to_string();

let target = HashMap::from([(name, fullpath)]);

if let Err(e) = WebBundler::new(&target, &self.cache_dir.dir_path()).exec() {
return Err(anyhow!("Cannot bundling head: {e}"));
}

// TODO: remove this line
sleep(Duration::from_millis(500));

let _ = loaders::from_single_file(
"node",
format!("{}/head.js", self.cache_dir.dir_path().display()),
);
IS_HEAD_SCRIPT_LOADED.lock().unwrap().loaded()
}
match metacall_no_arg::<String>("render_head") {
Err(e) => Err(anyhow!("Couldn't render head: {e:?}")),
Ok(out) => Ok(out),
Expand Down
10 changes: 10 additions & 0 deletions crates/metassr-create/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "metassr-create"
version = "0.1.0"
edition = "2021"
build = "build.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[build-dependencies]
walkdir = "2.5.0"
45 changes: 45 additions & 0 deletions crates/metassr-create/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::env;
use std::fs;
use std::path::PathBuf;
use walkdir::WalkDir;

fn main() {
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let dest_path = out_dir.join("templates.rs");
println!("==> {dest_path:#?}");
let templates_dir = "templates";
let mut generated_code = String::new();

generated_code.push_str("use std::collections::HashMap;\n\n");
generated_code
.push_str("pub fn load_templates() -> HashMap<String, HashMap<String, String>> {\n");
generated_code.push_str(" let mut templates = HashMap::new();\n");

for entry in WalkDir::new(templates_dir)
.into_iter()
.filter_map(Result::ok)
.filter(|e| e.file_type().is_file())
{
let path = entry.path();
let relative_path = path.strip_prefix(templates_dir).unwrap().to_str().unwrap();
let template_name = relative_path.split('/').next().unwrap();
let file_name = relative_path
.split('/')
.skip(1)
.collect::<Vec<_>>()
.join("/");

generated_code.push_str(&format!(
" templates.entry(\"{}\".to_string()).or_insert_with(HashMap::new).insert(\"{}\".to_string(), include_str!(r#\"{}\"#).to_string());\n",
template_name,
file_name,
path.display()
));
}

generated_code.push_str(" templates\n");
generated_code.push_str("}\n");

fs::write(&dest_path, generated_code).unwrap();
println!("cargo:rerun-if-changed={}", templates_dir);
}
14 changes: 14 additions & 0 deletions crates/metassr-create/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub fn add(left: usize, right: usize) -> usize {
left + right
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
27 changes: 27 additions & 0 deletions crates/metassr-create/templates/javascript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# metassr
/dist


# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
metassr.log*

# local env files
.env*.local
Loading

0 comments on commit 80244af

Please sign in to comment.