@ape-egg/vibe-compiler 4.0.1 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/native/vibe-compiler-darwin-arm64 +0 -0
- package/native/vibe-compiler-linux-x64 +0 -0
- package/package.json +1 -1
- package/src/Cargo.lock +1 -1
- package/src/Cargo.toml +1 -1
- package/src/compiler/compile.rs +62 -0
- package/src/config.rs +5 -0
- package/src/main.rs +7 -0
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ape-egg/vibe-compiler",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Optional Rust compiler for Vibe — pre-renders, inlines components, and optimizes iterations. The runtime never needs it.",
|
|
6
6
|
"homepage": "https://vibe.korte.kim",
|
package/src/Cargo.lock
CHANGED
package/src/Cargo.toml
CHANGED
package/src/compiler/compile.rs
CHANGED
|
@@ -62,6 +62,38 @@ pub(crate) fn atomic_write(path: &Path, contents: &str) -> std::io::Result<()> {
|
|
|
62
62
|
// Can be used as class (.vibe-fouc) or attribute ([vibe-fouc])
|
|
63
63
|
const FOUC_CLASS_OR_ATTR: &str = "vibe-fouc";
|
|
64
64
|
|
|
65
|
+
const VIBE_CSS_FILE: &str = include_str!("../../../vibe/vibe.css");
|
|
66
|
+
const VIBE_CSS_OPTIONAL_MARKER: &str =
|
|
67
|
+
"/* vibe:optional — everything below is skipped by disableVibeCss */";
|
|
68
|
+
|
|
69
|
+
fn strip_css_comments(css: &str) -> String {
|
|
70
|
+
let mut out = String::with_capacity(css.len());
|
|
71
|
+
let mut rest = css;
|
|
72
|
+
while let Some(start) = rest.find("/*") {
|
|
73
|
+
out.push_str(&rest[..start]);
|
|
74
|
+
rest = match rest[start..].find("*/") {
|
|
75
|
+
Some(end) => &rest[start + end + 2..],
|
|
76
|
+
None => "",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
out.push_str(rest);
|
|
80
|
+
out
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fn single_line_css(css: &str) -> String {
|
|
84
|
+
strip_css_comments(css)
|
|
85
|
+
.split_whitespace()
|
|
86
|
+
.collect::<Vec<_>>()
|
|
87
|
+
.join(" ")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
fn vibe_css_sheets() -> (String, String) {
|
|
91
|
+
let (cover, layout) = VIBE_CSS_FILE
|
|
92
|
+
.split_once(VIBE_CSS_OPTIONAL_MARKER)
|
|
93
|
+
.expect("vibe.css lost its optional marker");
|
|
94
|
+
(single_line_css(cover), single_line_css(layout))
|
|
95
|
+
}
|
|
96
|
+
|
|
65
97
|
const MIRROR_EXTENSIONS: &[&str] = &[
|
|
66
98
|
"css", "js",
|
|
67
99
|
// Fonts
|
|
@@ -246,6 +278,29 @@ fn remove_fouc_prevention(html: String) -> String {
|
|
|
246
278
|
result
|
|
247
279
|
}
|
|
248
280
|
|
|
281
|
+
pub fn inject_vibe_css(html: String, disable_vibe_css: bool) -> String {
|
|
282
|
+
if html.contains("data-vibe-cover") {
|
|
283
|
+
return html;
|
|
284
|
+
}
|
|
285
|
+
let open_end = match html.find("<head") {
|
|
286
|
+
Some(at) => match html[at..].find('>') {
|
|
287
|
+
Some(close) => at + close + 1,
|
|
288
|
+
None => return html,
|
|
289
|
+
},
|
|
290
|
+
None => return html,
|
|
291
|
+
};
|
|
292
|
+
let (cover_css, layout_css) = vibe_css_sheets();
|
|
293
|
+
let mut style = format!("<style data-vibe-cover>{}</style>", cover_css);
|
|
294
|
+
if !disable_vibe_css {
|
|
295
|
+
style.push_str(&format!("<style data-vibe-css>{}</style>", layout_css));
|
|
296
|
+
}
|
|
297
|
+
let mut result = String::with_capacity(html.len() + style.len());
|
|
298
|
+
result.push_str(&html[..open_end]);
|
|
299
|
+
result.push_str(&style);
|
|
300
|
+
result.push_str(&html[open_end..]);
|
|
301
|
+
result
|
|
302
|
+
}
|
|
303
|
+
|
|
249
304
|
#[derive(Error, Debug)]
|
|
250
305
|
pub enum CompileError {
|
|
251
306
|
#[error("Source directory not found: {0}")]
|
|
@@ -1454,6 +1509,8 @@ impl Compiler {
|
|
|
1454
1509
|
output = remove_fouc_prevention(output);
|
|
1455
1510
|
}
|
|
1456
1511
|
|
|
1512
|
+
output = inject_vibe_css(output, self.config.disable_vibe_css);
|
|
1513
|
+
|
|
1457
1514
|
// Write to output
|
|
1458
1515
|
let output_path = self.get_output_path(path, relative_path)?;
|
|
1459
1516
|
atomic_write(&output_path, &output).map_err(|e| CompileError::WriteError {
|
|
@@ -1739,6 +1796,7 @@ impl Compiler {
|
|
|
1739
1796
|
} else {
|
|
1740
1797
|
shell_processed
|
|
1741
1798
|
};
|
|
1799
|
+
let shell_html = inject_vibe_css(shell_html, self.config.disable_vibe_css);
|
|
1742
1800
|
let shell_path = self.config.output.join("index.html");
|
|
1743
1801
|
atomic_write(&shell_path, &shell_html).map_err(|e| CompileError::WriteError {
|
|
1744
1802
|
path: shell_path.display().to_string(),
|
|
@@ -2825,6 +2883,7 @@ mod tests {
|
|
|
2825
2883
|
iterations_as_is: false,
|
|
2826
2884
|
no_clean: false,
|
|
2827
2885
|
fouc_as_is: false,
|
|
2886
|
+
disable_vibe_css: false,
|
|
2828
2887
|
spa: true,
|
|
2829
2888
|
working_dir: dir.clone(),
|
|
2830
2889
|
};
|
|
@@ -2913,6 +2972,7 @@ mod tests {
|
|
|
2913
2972
|
iterations_as_is: false,
|
|
2914
2973
|
no_clean: false,
|
|
2915
2974
|
fouc_as_is: false,
|
|
2975
|
+
disable_vibe_css: false,
|
|
2916
2976
|
spa: true,
|
|
2917
2977
|
working_dir: dir.clone(),
|
|
2918
2978
|
};
|
|
@@ -3025,6 +3085,7 @@ mod tests {
|
|
|
3025
3085
|
iterations_as_is: false,
|
|
3026
3086
|
no_clean: false,
|
|
3027
3087
|
fouc_as_is: false,
|
|
3088
|
+
disable_vibe_css: false,
|
|
3028
3089
|
spa: true,
|
|
3029
3090
|
working_dir: dir.clone(),
|
|
3030
3091
|
};
|
|
@@ -3096,6 +3157,7 @@ mod tests {
|
|
|
3096
3157
|
iterations_as_is: false,
|
|
3097
3158
|
no_clean: false,
|
|
3098
3159
|
fouc_as_is: false,
|
|
3160
|
+
disable_vibe_css: false,
|
|
3099
3161
|
spa: false,
|
|
3100
3162
|
working_dir: dir.clone(),
|
|
3101
3163
|
};
|
package/src/config.rs
CHANGED
|
@@ -48,6 +48,8 @@ pub struct VibeCompilerConfig {
|
|
|
48
48
|
pub no_clean: bool,
|
|
49
49
|
#[serde(default)]
|
|
50
50
|
pub fouc_as_is: bool,
|
|
51
|
+
#[serde(default)]
|
|
52
|
+
pub disable_vibe_css: bool,
|
|
51
53
|
#[serde(default, deserialize_with = "deserialize_spa")]
|
|
52
54
|
pub spa: bool,
|
|
53
55
|
}
|
|
@@ -121,6 +123,7 @@ impl Default for VibeCompilerConfig {
|
|
|
121
123
|
iterations_as_is: false,
|
|
122
124
|
no_clean: false,
|
|
123
125
|
fouc_as_is: false,
|
|
126
|
+
disable_vibe_css: false,
|
|
124
127
|
spa: false,
|
|
125
128
|
}
|
|
126
129
|
}
|
|
@@ -147,6 +150,7 @@ pub struct Config {
|
|
|
147
150
|
pub iterations_as_is: bool,
|
|
148
151
|
pub no_clean: bool,
|
|
149
152
|
pub fouc_as_is: bool,
|
|
153
|
+
pub disable_vibe_css: bool,
|
|
150
154
|
pub spa: bool,
|
|
151
155
|
pub working_dir: PathBuf,
|
|
152
156
|
}
|
|
@@ -209,6 +213,7 @@ impl Config {
|
|
|
209
213
|
iterations_as_is: config.iterations_as_is,
|
|
210
214
|
no_clean: config.no_clean,
|
|
211
215
|
fouc_as_is: config.fouc_as_is,
|
|
216
|
+
disable_vibe_css: config.disable_vibe_css,
|
|
212
217
|
spa: config.spa,
|
|
213
218
|
working_dir,
|
|
214
219
|
}
|
package/src/main.rs
CHANGED
|
@@ -89,6 +89,10 @@ struct Args {
|
|
|
89
89
|
#[arg(long, name = "fouc-as-is")]
|
|
90
90
|
fouc_as_is: bool,
|
|
91
91
|
|
|
92
|
+
/// Skip emitting vibe's optional layout CSS (the cover rules always emit)
|
|
93
|
+
#[arg(long, name = "disable-vibe-css")]
|
|
94
|
+
disable_vibe_css: bool,
|
|
95
|
+
|
|
92
96
|
/// Compile the pages tree to SPA output: fragments + route table + shell
|
|
93
97
|
#[arg(long)]
|
|
94
98
|
spa: bool,
|
|
@@ -171,6 +175,9 @@ fn main() {
|
|
|
171
175
|
if args.fouc_as_is {
|
|
172
176
|
config.fouc_as_is = true;
|
|
173
177
|
}
|
|
178
|
+
if args.disable_vibe_css {
|
|
179
|
+
config.disable_vibe_css = true;
|
|
180
|
+
}
|
|
174
181
|
if args.spa {
|
|
175
182
|
overrides.spa = !original_spa;
|
|
176
183
|
config.spa = true;
|