@ape-egg/vibe 1.3.2 → 1.6.1
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/CHANGELOG.md +195 -0
- package/README.md +214 -16
- package/boot.js +0 -1
- package/compiler/native/vibe-compiler-darwin-arm64 +0 -0
- package/compiler/src/Cargo.lock +720 -41
- package/compiler/src/Cargo.toml +12 -3
- package/compiler/src/compiler/PRE-RENDERING-IMPLEMENTATION.md +241 -0
- package/compiler/src/compiler/compile.rs +562 -180
- package/compiler/src/compiler/component_tagger.rs +234 -0
- package/compiler/src/compiler/iteration_optimizer.rs +351 -0
- package/compiler/src/compiler/js_analyzer.rs +572 -0
- package/compiler/src/compiler/manifest_builder.rs +251 -26
- package/compiler/src/compiler/mod.rs +5 -1
- package/compiler/src/compiler/state_extractor.rs +140 -25
- package/compiler/src/compiler/value_stamper.rs +579 -88
- package/compiler/src/compiler/watcher.rs +579 -0
- package/compiler/src/config.rs +51 -8
- package/compiler/src/main.rs +47 -31
- package/compiler/src/parser/html.rs +229 -118
- package/component.js +23 -11
- package/package.json +1 -1
- package/runtime/cleanup.js +4 -4
- package/runtime/component.js +98 -21
- package/runtime/conditionals.js +2 -2
- package/runtime/constants.js +2 -1
- package/runtime/index.js +152 -30
- package/runtime/iterate.js +27 -5
- package/runtime/parse.js +2 -1
- package/runtime/pre-compiled-iterations.js +153 -0
- package/runtime/{hyperspeed.js → pre-compiled-manifest.js} +219 -133
- package/runtime/utils.js +2 -1
- package/test-results/.last-run.json +4 -0
- package/vibe.css +19 -0
- package/runtime/component-state.js +0 -63
package/compiler/src/config.rs
CHANGED
|
@@ -29,17 +29,21 @@ pub struct VibeCompilerConfig {
|
|
|
29
29
|
#[serde(default)]
|
|
30
30
|
pub minify: bool,
|
|
31
31
|
#[serde(default)]
|
|
32
|
-
pub
|
|
32
|
+
pub elements_as_is: bool,
|
|
33
33
|
#[serde(default)]
|
|
34
34
|
pub validate: bool,
|
|
35
35
|
#[serde(default)]
|
|
36
36
|
pub source_maps: bool,
|
|
37
37
|
#[serde(default)]
|
|
38
|
-
pub
|
|
38
|
+
pub reserved_elements: Vec<String>,
|
|
39
39
|
#[serde(default)]
|
|
40
40
|
pub node_modules_as_is: bool,
|
|
41
41
|
#[serde(default)]
|
|
42
42
|
pub components_as_is: bool,
|
|
43
|
+
#[serde(default)]
|
|
44
|
+
pub runtime_as_is: bool,
|
|
45
|
+
#[serde(default)]
|
|
46
|
+
pub iterations_as_is: bool,
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
fn default_source() -> String { "./".to_string() }
|
|
@@ -48,6 +52,35 @@ fn default_components() -> String { "components".to_string() }
|
|
|
48
52
|
fn default_pages() -> String { "pages".to_string() }
|
|
49
53
|
fn default_assets() -> String { "assets".to_string() }
|
|
50
54
|
|
|
55
|
+
/// Get list of standard HTML5 elements + "component"
|
|
56
|
+
/// Component names matching these are reserved and not allowed
|
|
57
|
+
pub fn get_default_reserved_elements() -> Vec<String> {
|
|
58
|
+
vec![
|
|
59
|
+
"a", "abbr", "address", "area", "article", "aside", "audio",
|
|
60
|
+
"b", "base", "bdi", "bdo", "blockquote", "body", "br", "button",
|
|
61
|
+
"canvas", "caption", "cite", "code", "col", "colgroup",
|
|
62
|
+
"data", "datalist", "dd", "del", "details", "dfn", "dialog", "div", "dl", "dt",
|
|
63
|
+
"em", "embed",
|
|
64
|
+
"fieldset", "figcaption", "figure", "footer", "form",
|
|
65
|
+
"h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html",
|
|
66
|
+
"i", "iframe", "img", "input", "ins",
|
|
67
|
+
"kbd",
|
|
68
|
+
"label", "legend", "li", "link",
|
|
69
|
+
"main", "map", "mark", "menu", "meta", "meter",
|
|
70
|
+
"nav", "noscript",
|
|
71
|
+
"object", "ol", "optgroup", "option", "output",
|
|
72
|
+
"p", "param", "picture", "pre", "progress",
|
|
73
|
+
"q",
|
|
74
|
+
"rp", "rt", "ruby",
|
|
75
|
+
"s", "samp", "script", "search", "section", "select", "slot", "small", "source", "span", "strong", "style", "sub", "summary", "sup", "svg",
|
|
76
|
+
"table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track",
|
|
77
|
+
"u", "ul",
|
|
78
|
+
"var", "video",
|
|
79
|
+
"wbr",
|
|
80
|
+
"component", // Always reserved
|
|
81
|
+
].into_iter().map(|s| s.to_string()).collect()
|
|
82
|
+
}
|
|
83
|
+
|
|
51
84
|
impl Default for VibeCompilerConfig {
|
|
52
85
|
fn default() -> Self {
|
|
53
86
|
Self {
|
|
@@ -58,12 +91,14 @@ impl Default for VibeCompilerConfig {
|
|
|
58
91
|
assets: default_assets(),
|
|
59
92
|
root: None,
|
|
60
93
|
minify: false,
|
|
61
|
-
|
|
94
|
+
elements_as_is: false,
|
|
62
95
|
validate: false,
|
|
63
96
|
source_maps: false,
|
|
64
|
-
|
|
97
|
+
reserved_elements: vec![],
|
|
65
98
|
node_modules_as_is: false,
|
|
66
99
|
components_as_is: false,
|
|
100
|
+
runtime_as_is: false,
|
|
101
|
+
iterations_as_is: false,
|
|
67
102
|
}
|
|
68
103
|
}
|
|
69
104
|
}
|
|
@@ -79,12 +114,14 @@ pub struct Config {
|
|
|
79
114
|
pub _assets: String,
|
|
80
115
|
pub _root: Option<String>,
|
|
81
116
|
pub minify: bool,
|
|
82
|
-
pub
|
|
117
|
+
pub elements_as_is: bool,
|
|
83
118
|
pub validate: bool,
|
|
84
119
|
pub source_maps: bool,
|
|
85
|
-
pub
|
|
120
|
+
pub reserved_elements: Vec<String>,
|
|
86
121
|
pub node_modules_as_is: bool,
|
|
87
122
|
pub components_as_is: bool,
|
|
123
|
+
pub runtime_as_is: bool,
|
|
124
|
+
pub iterations_as_is: bool,
|
|
88
125
|
pub working_dir: PathBuf,
|
|
89
126
|
}
|
|
90
127
|
|
|
@@ -109,6 +146,10 @@ impl Config {
|
|
|
109
146
|
let source = working_dir.join(&config.source);
|
|
110
147
|
let output = working_dir.join(&config.output);
|
|
111
148
|
|
|
149
|
+
// Combine default reserved elements with user-provided ones
|
|
150
|
+
let mut reserved_elements = get_default_reserved_elements();
|
|
151
|
+
reserved_elements.extend(config.reserved_elements);
|
|
152
|
+
|
|
112
153
|
Self {
|
|
113
154
|
source,
|
|
114
155
|
output,
|
|
@@ -119,12 +160,14 @@ impl Config {
|
|
|
119
160
|
_assets: config.assets,
|
|
120
161
|
_root: config.root,
|
|
121
162
|
minify: config.minify,
|
|
122
|
-
|
|
163
|
+
elements_as_is: config.elements_as_is,
|
|
123
164
|
validate: config.validate,
|
|
124
165
|
source_maps: config.source_maps,
|
|
125
|
-
|
|
166
|
+
reserved_elements,
|
|
126
167
|
node_modules_as_is: config.node_modules_as_is,
|
|
127
168
|
components_as_is: config.components_as_is,
|
|
169
|
+
runtime_as_is: config.runtime_as_is,
|
|
170
|
+
iterations_as_is: config.iterations_as_is,
|
|
128
171
|
working_dir,
|
|
129
172
|
}
|
|
130
173
|
}
|
package/compiler/src/main.rs
CHANGED
|
@@ -7,26 +7,26 @@ use colored::Colorize;
|
|
|
7
7
|
use std::path::PathBuf;
|
|
8
8
|
|
|
9
9
|
use config::Config;
|
|
10
|
-
use compiler::compile::CompileError;
|
|
11
10
|
use compiler::Compiler;
|
|
12
11
|
|
|
13
12
|
/// Track which config values were overridden by flags
|
|
14
13
|
#[derive(Debug, Default)]
|
|
15
14
|
struct ConfigOverrides {
|
|
16
15
|
minify: bool,
|
|
17
|
-
|
|
16
|
+
elements_as_is: bool,
|
|
18
17
|
validate: bool,
|
|
19
18
|
source_maps: bool,
|
|
20
19
|
node_modules_as_is: bool,
|
|
21
20
|
components_as_is: bool,
|
|
22
21
|
runtime_as_is: bool,
|
|
22
|
+
iterations_as_is: bool,
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/// Vibe Compiler - Compiles Vibe source files into optimized output
|
|
26
26
|
#[derive(ClapParser, Debug)]
|
|
27
27
|
#[command(name = "vibe-compile")]
|
|
28
28
|
#[command(author = "Kim Korte")]
|
|
29
|
-
#[command(version = "
|
|
29
|
+
#[command(version = "1.6.1")]
|
|
30
30
|
#[command(about = "Compiles Vibe source files into optimized output")]
|
|
31
31
|
struct Args {
|
|
32
32
|
/// Working directory (defaults to current directory)
|
|
@@ -45,9 +45,9 @@ struct Args {
|
|
|
45
45
|
#[arg(long)]
|
|
46
46
|
verbose: bool,
|
|
47
47
|
|
|
48
|
-
///
|
|
49
|
-
#[arg(long)]
|
|
50
|
-
|
|
48
|
+
/// Keep custom HTML elements as-is (don't transform to divs for accessibility)
|
|
49
|
+
#[arg(long, name = "elements-as-is")]
|
|
50
|
+
elements_as_is: bool,
|
|
51
51
|
|
|
52
52
|
/// Generate source maps
|
|
53
53
|
#[arg(long, name = "source-maps")]
|
|
@@ -80,6 +80,10 @@ struct Args {
|
|
|
80
80
|
/// Skip manifest generation - output will use runtime-only mode (no FOUC prevention)
|
|
81
81
|
#[arg(long, name = "runtime-as-is")]
|
|
82
82
|
runtime_as_is: bool,
|
|
83
|
+
|
|
84
|
+
/// Skip iteration optimization - use runtime DOM cloning instead of compiled batch functions
|
|
85
|
+
#[arg(long, name = "iterations-as-is")]
|
|
86
|
+
iterations_as_is: bool,
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
fn main() {
|
|
@@ -114,11 +118,13 @@ fn main() {
|
|
|
114
118
|
|
|
115
119
|
// Store original config values before applying flag overrides
|
|
116
120
|
let original_minify = config.minify;
|
|
117
|
-
let
|
|
121
|
+
let original_elements_as_is = config.elements_as_is;
|
|
118
122
|
let original_validate = config.validate;
|
|
119
123
|
let original_source_maps = config.source_maps;
|
|
120
124
|
let original_node_modules_as_is = config.node_modules_as_is;
|
|
121
125
|
let original_components_as_is = config.components_as_is;
|
|
126
|
+
let original_runtime_as_is = config.runtime_as_is;
|
|
127
|
+
let original_iterations_as_is = config.iterations_as_is;
|
|
122
128
|
|
|
123
129
|
// Track overrides for verbose output
|
|
124
130
|
let mut overrides = ConfigOverrides::default();
|
|
@@ -127,9 +133,9 @@ fn main() {
|
|
|
127
133
|
overrides.minify = !original_minify;
|
|
128
134
|
config.minify = true;
|
|
129
135
|
}
|
|
130
|
-
if args.
|
|
131
|
-
overrides.
|
|
132
|
-
config.
|
|
136
|
+
if args.elements_as_is {
|
|
137
|
+
overrides.elements_as_is = !original_elements_as_is;
|
|
138
|
+
config.elements_as_is = true;
|
|
133
139
|
}
|
|
134
140
|
if args.validate {
|
|
135
141
|
overrides.validate = !original_validate;
|
|
@@ -147,9 +153,17 @@ fn main() {
|
|
|
147
153
|
overrides.components_as_is = !original_components_as_is;
|
|
148
154
|
config.components_as_is = true;
|
|
149
155
|
}
|
|
156
|
+
if args.runtime_as_is {
|
|
157
|
+
overrides.runtime_as_is = !original_runtime_as_is;
|
|
158
|
+
config.runtime_as_is = true;
|
|
159
|
+
}
|
|
160
|
+
if args.iterations_as_is {
|
|
161
|
+
overrides.iterations_as_is = !original_iterations_as_is;
|
|
162
|
+
config.iterations_as_is = true;
|
|
163
|
+
}
|
|
150
164
|
|
|
151
165
|
if args.verbose {
|
|
152
|
-
println!("{}", "Vibe Compiler".cyan().bold());
|
|
166
|
+
println!("{}", format!("Vibe Compiler v{}", env!("CARGO_PKG_VERSION")).cyan().bold());
|
|
153
167
|
println!();
|
|
154
168
|
println!(" {}: {}", "Working dir".cyan(), config.working_dir.display());
|
|
155
169
|
println!(" {}: {}", "Source".cyan(), config.source.display());
|
|
@@ -178,31 +192,46 @@ fn main() {
|
|
|
178
192
|
}
|
|
179
193
|
|
|
180
194
|
// Alphabetically ordered with padding (longest key is "node-modules-as-is" = 18 chars)
|
|
181
|
-
println!(" {}: {}", format!("{:<18}", "accessibility").cyan(), format_bool_with_flag(config.accessibility, overrides.accessibility, original_accessibility));
|
|
182
195
|
println!(" {}: {}", format!("{:<18}", "assets").cyan(), format_value_no_flag(&config._assets));
|
|
183
196
|
println!(" {}: {}", format!("{:<18}", "components").cyan(), format_value_no_flag(&config.components));
|
|
184
197
|
println!(" {}: {}", format!("{:<18}", "components-as-is").cyan(), format_bool_with_flag(config.components_as_is, overrides.components_as_is, original_components_as_is));
|
|
185
|
-
println!(" {}: {}", format!("{:<18}", "
|
|
198
|
+
println!(" {}: {}", format!("{:<18}", "elements-as-is").cyan(), format_bool_with_flag(config.elements_as_is, overrides.elements_as_is, original_elements_as_is));
|
|
199
|
+
println!(" {}: {}", format!("{:<18}", "exclude-tags").cyan(), format_value_no_flag(format!("{:?}", config.reserved_elements)));
|
|
186
200
|
println!(" {}: {}", format!("{:<18}", "minify").cyan(), format_bool_with_flag(config.minify, overrides.minify, original_minify));
|
|
187
201
|
println!(" {}: {}", format!("{:<18}", "node-modules-as-is").cyan(), format_bool_with_flag(config.node_modules_as_is, overrides.node_modules_as_is, original_node_modules_as_is));
|
|
188
202
|
println!(" {}: {}", format!("{:<18}", "output").cyan(), format_value_no_flag(&config._output_str));
|
|
189
203
|
println!(" {}: {}", format!("{:<18}", "pages").cyan(), format_value_no_flag(&config.pages));
|
|
190
204
|
println!(" {}: {}", format!("{:<18}", "root").cyan(), format_value_no_flag(config._root.as_ref().map(|s| s.as_str()).unwrap_or("null")));
|
|
191
|
-
println!(" {}: {}", format!("{:<18}", "runtime-as-is").cyan(),
|
|
205
|
+
println!(" {}: {}", format!("{:<18}", "runtime-as-is").cyan(), format_bool_with_flag(config.runtime_as_is, overrides.runtime_as_is, original_runtime_as_is));
|
|
192
206
|
println!(" {}: {}", format!("{:<18}", "source").cyan(), format_value_no_flag(&config._source_str));
|
|
193
207
|
println!(" {}: {}", format!("{:<18}", "source-maps").cyan(), format_bool_with_flag(config.source_maps, overrides.source_maps, original_source_maps));
|
|
194
208
|
println!(" {}: {}", format!("{:<18}", "validate").cyan(), format_bool_with_flag(config.validate, overrides.validate, original_validate));
|
|
195
209
|
println!();
|
|
210
|
+
} else {
|
|
211
|
+
// Show version in non-verbose mode
|
|
212
|
+
println!("{}", format!("Vibe Compiler v{}", env!("CARGO_PKG_VERSION")).cyan());
|
|
196
213
|
}
|
|
197
214
|
|
|
215
|
+
// Handle watch mode
|
|
216
|
+
if args.watch {
|
|
217
|
+
if let Err(e) = compiler::watcher::watch(config, args.verbose) {
|
|
218
|
+
eprintln!("{}: {}", "Error".red(), e);
|
|
219
|
+
std::process::exit(1);
|
|
220
|
+
}
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Save runtime_as_is before moving config
|
|
225
|
+
let runtime_as_is = config.runtime_as_is;
|
|
226
|
+
|
|
198
227
|
let mut compiler = Compiler::new(config, args.verbose);
|
|
199
228
|
|
|
200
229
|
match compiler.compile() {
|
|
201
230
|
Ok(stats) => {
|
|
202
|
-
// Generate manifests BEFORE showing success (unless
|
|
231
|
+
// Generate manifests BEFORE showing success (unless runtime-as-is is enabled)
|
|
203
232
|
let mut manifest_time_ms = 0.0;
|
|
204
233
|
let mut manifest_stats_result = None;
|
|
205
|
-
if !
|
|
234
|
+
if !runtime_as_is {
|
|
206
235
|
match compiler.generate_manifests() {
|
|
207
236
|
Ok(manifest_stats) => {
|
|
208
237
|
manifest_time_ms = manifest_stats.total_time_ms;
|
|
@@ -217,7 +246,7 @@ fn main() {
|
|
|
217
246
|
}
|
|
218
247
|
|
|
219
248
|
// Show success headline
|
|
220
|
-
println!("\n{}", "Compilation successful! ✅".green().bold());
|
|
249
|
+
println!("\n{}", format!("Compilation successful! (v{}) ✅", env!("CARGO_PKG_VERSION")).green().bold());
|
|
221
250
|
println!();
|
|
222
251
|
|
|
223
252
|
// Show individual phase timings (validation first, then components, HTML, manifests, copied)
|
|
@@ -289,20 +318,7 @@ fn main() {
|
|
|
289
318
|
std::process::exit(0);
|
|
290
319
|
}
|
|
291
320
|
Err(e) => {
|
|
292
|
-
|
|
293
|
-
CompileError::ComponentValidationFailed(errors) => {
|
|
294
|
-
eprintln!("\n{}: Component validation failed\n", "Error".red());
|
|
295
|
-
for err in errors {
|
|
296
|
-
eprintln!(" {} {}", "✗".red(), err.component_src);
|
|
297
|
-
eprintln!(" Referenced in: {}", err.referenced_in);
|
|
298
|
-
eprintln!(" Error: {}\n", err.error_message);
|
|
299
|
-
}
|
|
300
|
-
eprintln!("Fix the errors above and try again.");
|
|
301
|
-
}
|
|
302
|
-
_ => {
|
|
303
|
-
eprintln!("{}: {}", "Error".red(), e);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
321
|
+
eprintln!("{}: {}", "Error".red(), e);
|
|
306
322
|
std::process::exit(1);
|
|
307
323
|
}
|
|
308
324
|
}
|