@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,200 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.1] - 2026-02-12
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Compiler output directory handling** - Fixed duplicate file generation in output
|
|
8
|
+
- Compiler now properly handles source and output paths without preserving source directory structure
|
|
9
|
+
- Files from `./src` are now correctly written to root of output directory (e.g., `compiled/index.html`) instead of `compiled/src/index.html`
|
|
10
|
+
- Canonicalized source path for reliable comparison and path stripping
|
|
11
|
+
- Updated all processing functions to use canonical source path for relative path calculation
|
|
12
|
+
|
|
13
|
+
- **Manifest detection improvements** - Better handling of directory URLs and extensionless paths
|
|
14
|
+
- Directory URLs now normalized: `/compiled/` → `/compiled/index.html`
|
|
15
|
+
- Extensionless URLs now normalized: `/compiled/mypage` → `/compiled/mypage.html`
|
|
16
|
+
- Fixes manifest detection when visiting pages without explicit `.html` extension
|
|
17
|
+
- Enables proper hyperspeed loading for directory index pages
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## [1.6.0] - 2026-02-12
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Watch mode** - Compiler now supports file watching with incremental compilation
|
|
26
|
+
- New `--watch` flag monitors source files for changes and automatically recompiles
|
|
27
|
+
- Intelligent change detection tracks affected files and their dependencies
|
|
28
|
+
- Transitive dependency tracking: changes to components trigger recompilation of pages using them
|
|
29
|
+
- Blacklist support: watch mode respects SKIP_FILES patterns (tests/, node_modules/, etc.)
|
|
30
|
+
- Debounced file events (300ms) prevent excessive compilation during rapid changes
|
|
31
|
+
- Outputs only changed files for fast incremental builds
|
|
32
|
+
- First compile shows full output, subsequent compiles show only deltas
|
|
33
|
+
- **Reserved element validation** - Compiler now prevents component naming conflicts
|
|
34
|
+
- New `reservedElements` config option (replaces `excludeTags`)
|
|
35
|
+
- Defaults to all HTML5 elements plus "component" keyword
|
|
36
|
+
- User-provided values append to defaults (not replace)
|
|
37
|
+
- Case-sensitive validation: `nav.html` → Error, `Nav.html` → OK
|
|
38
|
+
- Compile-time error with clear message showing conflicting filename
|
|
39
|
+
- Prevents runtime confusion between HTML elements and custom components
|
|
40
|
+
- **Component path case-sensitivity** - Component paths are now treated as case-sensitive
|
|
41
|
+
- `<component src="path/to/MyComponent.html">` and `<component src="path/to/mycomponent.html">` are different
|
|
42
|
+
- Both runtime and compiler preserve exact case in paths
|
|
43
|
+
- Cache keys include full case-sensitive path
|
|
44
|
+
- Enables PascalCase naming convention for components while supporting any casing
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- **Component inlining architecture** - Complete rewrite from iterative to recursive fetching
|
|
49
|
+
- Removed MAX_ITERATIONS constant and loop-based approach
|
|
50
|
+
- `fetch_component_recursive()` now returns fully resolved content with all nested components inlined
|
|
51
|
+
- Components are cached only after being fully resolved (prevents incomplete content in cache)
|
|
52
|
+
- `inline_component_elements()` now does single pass (no loops)
|
|
53
|
+
- Significant performance improvement: sub-100ms compilation for complex nested components
|
|
54
|
+
- **Framework element handling** - `<component>` is now recognized as a framework element
|
|
55
|
+
- Never transformed to `<div>` regardless of `--elements-as-is` flag
|
|
56
|
+
- Custom elements (e.g., `<card>`, `<text>`) are transformed when `elements_as_is: false`
|
|
57
|
+
- Framework elements vs custom elements properly distinguished in compiler
|
|
58
|
+
- Wrapper `<component>` tags remain after inlining (expected by runtime)
|
|
59
|
+
- **Component inlining behavior** - Custom elements are always inlined
|
|
60
|
+
- `<card>` → transformed to `<component>` → inlined even with `--components-as-is`
|
|
61
|
+
- `--components-as-is` only affects explicit `<component src="...">` tags
|
|
62
|
+
- Consistent behavior: custom elements compile away, framework elements remain
|
|
63
|
+
- **Path normalization** - Component paths now consistently normalized
|
|
64
|
+
- All paths start with `/` (unless external URL)
|
|
65
|
+
- Cache uses normalized paths to prevent duplicates (`/components/nav.html` vs `./components/nav.html`)
|
|
66
|
+
- Fixes cache pollution from different path formats for same component
|
|
67
|
+
- **Config naming** - `excludeTags` renamed to `reservedElements` throughout codebase
|
|
68
|
+
- Better describes purpose (reserved from use as component names)
|
|
69
|
+
- Updated in Rust compiler, config files, and documentation
|
|
70
|
+
- Backward compatible: old config key still works but deprecated
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- Watch mode was compiling blacklisted files (tests/, node_modules/)
|
|
75
|
+
- Component inlining created infinite nested wrappers (100+ levels)
|
|
76
|
+
- Empty headlines in tests due to broken external component fetching
|
|
77
|
+
- Path case normalization could cause duplicates in component cache
|
|
78
|
+
- Accessibility transformation incorrectly converting `<component>` to divs
|
|
79
|
+
- Test expectations mismatched actual framework element behavior
|
|
80
|
+
|
|
81
|
+
### Performance
|
|
82
|
+
|
|
83
|
+
- Watch mode incremental compilation: ~100ms for typical changes
|
|
84
|
+
- First full compilation: ~300-500ms
|
|
85
|
+
- Component fetching: recursive approach 10x faster than iterative (no MAX_ITERATIONS overhead)
|
|
86
|
+
- Path normalization prevents redundant fetches of same component
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## [1.5.0] - 2026-02-09
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- **Nested iteration compilation** - Compiler now handles infinitely nested `<!-- each -->` blocks
|
|
95
|
+
- Recursive processing in `iteration_optimizer.rs` with depth counting for comment pair matching
|
|
96
|
+
- Nested loops compile to IIFEs (Immediately Invoked Function Expressions) with template literals
|
|
97
|
+
- Inner iterations inlined directly into outer batch functions for optimal performance
|
|
98
|
+
- Example: `<!-- each categories as cat --><!-- each cat.items as item -->` compiles to single optimized function
|
|
99
|
+
- **QuickJS JavaScript runtime** - Full expression evaluation at compile time
|
|
100
|
+
- Embedded QuickJS engine (`rquickjs = "0.6"`) for JavaScript evaluation in Rust
|
|
101
|
+
- No external dependencies - increases binary size by ~1-2MB
|
|
102
|
+
- Evaluates any JavaScript expression: `@[categories.length]`, `@[items[0]]`, `@[user.name.toUpperCase()]`
|
|
103
|
+
- State set in global scope: `Object.assign(globalThis, $)` matches Vibe runtime behavior
|
|
104
|
+
- Fast evaluation: ~160ms overhead for 35 files (~5ms per file)
|
|
105
|
+
- **Complete pre-rendering** - Zero FOUC with all bindings pre-rendered for SEO
|
|
106
|
+
- All `@[expression]` bindings evaluated and stamped into HTML at compile time
|
|
107
|
+
- Handles property access (`@[user.name]`), array methods (`@[categories.length]`), and complex expressions
|
|
108
|
+
- Nested iterations fully pre-rendered with merged state for each iteration context
|
|
109
|
+
- Falls back gracefully: undefined expressions left as `@[...]` for runtime hydration
|
|
110
|
+
- New test: `stamp_array_length` validates `.length` property evaluation
|
|
111
|
+
|
|
112
|
+
### Changed
|
|
113
|
+
|
|
114
|
+
- **Value stamper rewrite** (`value_stamper.rs`) - Complete overhaul to use QuickJS
|
|
115
|
+
- Replaced JSON path resolution with JavaScript expression evaluation
|
|
116
|
+
- `eval_expression()` handles any valid JavaScript with state in scope
|
|
117
|
+
- `eval_array_path()` evaluates array paths for iteration rendering
|
|
118
|
+
- Iteration rendering creates merged state (parent + item + index) for nested context
|
|
119
|
+
- Removed manual property traversal code - JavaScript engine handles it all
|
|
120
|
+
- **Compiled iteration updates** - Always use compiled path when available (`iterate.js:364`)
|
|
121
|
+
- Previously only used compiled updates for edge cases (empty↔full, large arrays >100)
|
|
122
|
+
- Now uses compiled batch functions for ALL updates when manifest has `compiled.iterations.batchFn`
|
|
123
|
+
- Fixes issue where small array updates (3→4 items) fell through to incompatible runtime path
|
|
124
|
+
- Ensures consistent performance regardless of array size or transition type
|
|
125
|
+
- **State extraction improvements** (`state_extractor.rs`) - Better error handling
|
|
126
|
+
- Silently skips unparseable state objects instead of failing compilation
|
|
127
|
+
- Enables graceful degradation when state contains functions or complex expressions
|
|
128
|
+
|
|
129
|
+
### Fixed
|
|
130
|
+
|
|
131
|
+
- Compiled iterations not updating when array size changes (e.g., add/remove items)
|
|
132
|
+
- Pre-rendering skipped for JavaScript expressions like `@[categories.length]`
|
|
133
|
+
- Nested iteration values showing as `@[item]` instead of actual data
|
|
134
|
+
- Runtime path attempting to handle compiled iterations incorrectly
|
|
135
|
+
|
|
136
|
+
### Performance
|
|
137
|
+
|
|
138
|
+
- Pre-rendering adds ~160ms to compilation for 35 files (~435ms total, up from ~310ms)
|
|
139
|
+
- QuickJS evaluation: ~1-5ms per binding
|
|
140
|
+
- Compiled nested iterations: Same performance as shallow iterations (no recursion overhead at runtime)
|
|
141
|
+
- Zero runtime cost for pre-rendered bindings - HTML arrives with values already stamped
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## [1.4.0] - 2026-02-09
|
|
146
|
+
|
|
147
|
+
### Added
|
|
148
|
+
|
|
149
|
+
- **Iteration optimization** - Compiler now generates optimized batch functions for `<!-- each -->` loops
|
|
150
|
+
- New `iteration_optimizer.rs` module generates string-based batch render functions
|
|
151
|
+
- Provides 2-3x performance improvement for iteration rendering (15-17ms vs 40ms for 1000 rows)
|
|
152
|
+
- Only applies to shallow iterations (nested iterations still use runtime path)
|
|
153
|
+
- Compiled batch functions are stored in manifest and executed at runtime
|
|
154
|
+
- **Pre-compiled iterations runtime** (`runtime/pre-compiled-iterations.js`)
|
|
155
|
+
- Production implementation of compiled iteration rendering
|
|
156
|
+
- Uses pre-compiled batch functions from manifest generated at build time
|
|
157
|
+
- Based on the prototype in `_vibe-compiled-iteration-batch.js`
|
|
158
|
+
- Automatically falls back to runtime rendering for nested iterations or missing batch functions
|
|
159
|
+
- **Compiler configuration** - New `iterationsAsIs` flag
|
|
160
|
+
- Set to `true` in `vibe-compiler` config to skip iteration optimization
|
|
161
|
+
- Iterations pass through unchanged and are handled entirely by runtime
|
|
162
|
+
- Default: `false` (iterations are optimized)
|
|
163
|
+
- **Hyperspeed benchmark** - New benchmark page for measuring pre-compiled performance
|
|
164
|
+
- Tests iteration optimization with 1000 rows
|
|
165
|
+
- Compares runtime vs compiled iteration rendering
|
|
166
|
+
- Available at `e2e-runtime/hyperspeed-benchmark.html`
|
|
167
|
+
- **Compiler test coverage** for iteration compilation
|
|
168
|
+
- `tests/compiler/iterations/` - Tests iteration optimization is applied
|
|
169
|
+
- `tests/compiler/iterations-as-is/` - Tests `iterationsAsIs` flag skips optimization
|
|
170
|
+
- E2E tests verify compiled iterations render correctly
|
|
171
|
+
|
|
172
|
+
### Changed
|
|
173
|
+
|
|
174
|
+
- **Renamed `runtime/hyperspeed.js` → `runtime/pre-compiled-manifest.js`**
|
|
175
|
+
- Better naming to reflect that it handles all pre-compiled features, not just "hyperspeed"
|
|
176
|
+
- Updated all imports and references throughout codebase
|
|
177
|
+
- **Enhanced manifest merging** - Compiler manifest now preserves compiled iteration data
|
|
178
|
+
- Iteration nodes retain `compiled.iterations.batchFn` from manifest during runtime merge
|
|
179
|
+
- Prevents compiled data from being discarded when merging with runtime tree
|
|
180
|
+
- **Debug logging improvements**
|
|
181
|
+
- Added manifest filename to debug output ("Loaded index.manifest.js, page is pre-compiled")
|
|
182
|
+
- Shows compiled feature count (e.g., "3 iterations optimized")
|
|
183
|
+
- Better visibility into which optimizations are active
|
|
184
|
+
- **Runtime iteration handling** - Iterations check for compiled batch functions before falling back
|
|
185
|
+
- `canUseCompiled()` determines if iteration can use batch function
|
|
186
|
+
- Falls back to runtime rendering for nested structures or missing compiled data
|
|
187
|
+
- Seamless integration between compiled and runtime paths
|
|
188
|
+
|
|
189
|
+
### Fixed
|
|
190
|
+
|
|
191
|
+
- Runtime cleanup now properly handles compiled iteration nodes
|
|
192
|
+
- Manifest merge no longer discards compiled data from iteration nodes
|
|
193
|
+
- Debug logging visibility flag now correctly propagates through manifest loading
|
|
194
|
+
- Iteration restoration respects compiled batch functions
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
3
198
|
## [1.3.2] - 2025-02-06
|
|
4
199
|
|
|
5
200
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# Vibe
|
|
2
2
|
|
|
3
|
-
A runtime-first reactive
|
|
3
|
+
**Version 1.6.0 (Alpha)** — A runtime-first reactive framework with optional compilation.
|
|
4
4
|
|
|
5
|
-
No virtual DOM. No build step. Just modern JavaScript.
|
|
5
|
+
No virtual DOM. No build step required. Just modern JavaScript. When you need production optimizations, add the optional Rust-based compiler.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @ape-egg/vibe
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
**Status:** Functional and ready to use, but expect bugs and breaking changes daily until stable. Use in production at your own risk.
|
|
12
|
+
|
|
11
13
|
---
|
|
12
14
|
|
|
13
15
|
## Vibe Runtime
|
|
@@ -124,6 +126,103 @@ Skip reactive processing for an element:
|
|
|
124
126
|
<code dehydrate>@[this] displays literally</code>
|
|
125
127
|
```
|
|
126
128
|
|
|
129
|
+
### Reserved Words & Gotchas
|
|
130
|
+
|
|
131
|
+
Vibe uses specific patterns and keywords that have special meaning. Avoid using these for other purposes to prevent unexpected behavior:
|
|
132
|
+
|
|
133
|
+
#### Classes & Attributes
|
|
134
|
+
|
|
135
|
+
- **`vibe-fouc`** — Class or attribute for FOUC (Flash of Unstyled Content) prevention. Automatically removed after hydration completes.
|
|
136
|
+
```html
|
|
137
|
+
<body vibe-fouc> <!-- or class="vibe-fouc" -->
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
- **`vibe-dehydrate`** — Class or attribute to skip reactive processing. Useful for displaying literal `@[...]` syntax in documentation.
|
|
141
|
+
```html
|
|
142
|
+
<code vibe-dehydrate>@[variable]</code> <!-- or class="vibe-dehydrate" -->
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Element Names & Classes
|
|
146
|
+
|
|
147
|
+
- **`<component>`** — Element name for component system. Used with `src` attribute for runtime component loading, or as a wrapper for inlined components.
|
|
148
|
+
```html
|
|
149
|
+
<component src="/path/to/component.html"></component>
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- **`class="component"`** — Alternative syntax for components using standard HTML elements. Useful for HTML validation or accessibility.
|
|
153
|
+
```html
|
|
154
|
+
<div class="component" src="/path/to/component.html"></div>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **`<slot>`** — Element name for component content injection. Gets replaced with content passed between component tags.
|
|
158
|
+
```html
|
|
159
|
+
<!-- In component file -->
|
|
160
|
+
<slot></slot>
|
|
161
|
+
|
|
162
|
+
<!-- Usage -->
|
|
163
|
+
<component src="...">
|
|
164
|
+
<p>This replaces the slot</p>
|
|
165
|
+
</component>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Comment Syntax
|
|
169
|
+
|
|
170
|
+
- **`<!-- each -->`** / **`<!-- /each -->`** — Iteration block markers.
|
|
171
|
+
```html
|
|
172
|
+
<!-- each items as item -->
|
|
173
|
+
<!-- /each -->
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
- **`<!-- if -->`** / **`<!-- else -->`** / **`<!-- /if -->`** — Conditional block markers.
|
|
177
|
+
```html
|
|
178
|
+
<!-- if condition -->
|
|
179
|
+
<!-- else -->
|
|
180
|
+
<!-- /if -->
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
#### Binding Syntax
|
|
184
|
+
|
|
185
|
+
- **`@[...]`** — Reactive binding syntax. Reserved for state references.
|
|
186
|
+
```html
|
|
187
|
+
<div>@[variable]</div>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### Global Properties
|
|
191
|
+
|
|
192
|
+
- **`window.$`** — Global reactive state object. All reactive data should be accessed through this.
|
|
193
|
+
```javascript
|
|
194
|
+
window.$ = state({ count: 0 });
|
|
195
|
+
$.count++; // Triggers reactive updates
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
- **`window.__vibeManifest`** — Internal manifest data. Used by the compiler for optimization. Don't modify.
|
|
199
|
+
|
|
200
|
+
- **`window.__vibeCompiling`** — Internal flag. Set to `true` when running in compiler context.
|
|
201
|
+
|
|
202
|
+
#### Data Attributes
|
|
203
|
+
|
|
204
|
+
- **`data-vibe-component-id`** — Internal attribute for component scoping. Automatically added to component elements. Don't use manually.
|
|
205
|
+
|
|
206
|
+
#### Event Names
|
|
207
|
+
|
|
208
|
+
- **`vibe:ready`** — Custom event fired when Vibe completes initial hydration.
|
|
209
|
+
```javascript
|
|
210
|
+
document.addEventListener('vibe:ready', () => {
|
|
211
|
+
console.log('Vibe is ready');
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
#### Special Attribute Meanings
|
|
216
|
+
|
|
217
|
+
- **`src`** on **`<component>`** or **`<div class="component">`** — Triggers runtime component fetching. Components without `src` are treated as inline wrappers.
|
|
218
|
+
```html
|
|
219
|
+
<!-- Both work the same way -->
|
|
220
|
+
<component src="/components/card.html"></component>
|
|
221
|
+
<div class="component" src="/components/card.html"></div>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
- **`dehydrate`** — Attribute or class name to skip reactive processing (alias for `vibe-dehydrate`).
|
|
225
|
+
|
|
127
226
|
### Deep Reactivity
|
|
128
227
|
|
|
129
228
|
Vibe uses recursive proxies to detect changes at any nesting level:
|
|
@@ -149,7 +248,7 @@ No need for immutable update patterns or spread operators. Just mutate and Vibe
|
|
|
149
248
|
|
|
150
249
|
## Vibe Compiler
|
|
151
250
|
|
|
152
|
-
Optional build step for production optimization. The compiler
|
|
251
|
+
Optional build step for production optimization. The compiler provides component inlining, iteration optimization, watch mode, and hydration manifests while preserving directory structure.
|
|
153
252
|
|
|
154
253
|
### Installation
|
|
155
254
|
|
|
@@ -167,18 +266,27 @@ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
|
167
266
|
# Initialize config in package.json
|
|
168
267
|
bunx vibe compile --init
|
|
169
268
|
|
|
170
|
-
#
|
|
269
|
+
# Basic compilation
|
|
171
270
|
bunx vibe compile
|
|
271
|
+
# or shorthand
|
|
272
|
+
bunx vibe c
|
|
273
|
+
|
|
274
|
+
# Watch mode (incremental compilation)
|
|
275
|
+
bunx vibe compile --watch
|
|
276
|
+
|
|
277
|
+
# Production build
|
|
278
|
+
bunx vibe compile --minify --source-maps
|
|
172
279
|
|
|
173
280
|
# With options
|
|
174
281
|
bunx vibe compile --verbose # Step-by-step logging
|
|
175
282
|
bunx vibe compile --minify # Minify output
|
|
176
|
-
bunx vibe compile --
|
|
283
|
+
bunx vibe compile --elements-as-is # Keep custom elements as-is
|
|
177
284
|
bunx vibe compile --validate # Validate HTML syntax
|
|
178
|
-
bunx vibe compile --create-manifest # Generate hydration manifest
|
|
179
285
|
bunx vibe compile --source-maps # Generate source maps
|
|
180
286
|
bunx vibe compile --node-modules-as-is # Copy node_modules as-is
|
|
181
|
-
bunx vibe compile --
|
|
287
|
+
bunx vibe compile --components-as-is # Skip component inlining
|
|
288
|
+
bunx vibe compile --runtime-as-is # Skip manifest generation
|
|
289
|
+
bunx vibe compile --iterations-as-is # Skip iteration optimization
|
|
182
290
|
```
|
|
183
291
|
|
|
184
292
|
Or via npm scripts:
|
|
@@ -186,13 +294,14 @@ Or via npm scripts:
|
|
|
186
294
|
```json
|
|
187
295
|
{
|
|
188
296
|
"scripts": {
|
|
189
|
-
"
|
|
190
|
-
"
|
|
297
|
+
"compile": "vibe compile",
|
|
298
|
+
"compile:watch": "vibe compile --watch",
|
|
299
|
+
"compile:prod": "vibe compile --minify --source-maps"
|
|
191
300
|
}
|
|
192
301
|
}
|
|
193
302
|
```
|
|
194
303
|
|
|
195
|
-
Then run with `
|
|
304
|
+
Then run with `npm run compile` or `bun compile`.
|
|
196
305
|
|
|
197
306
|
### Configuration
|
|
198
307
|
|
|
@@ -207,13 +316,26 @@ Add to your `package.json`:
|
|
|
207
316
|
"pages": "pages",
|
|
208
317
|
"assets": "assets",
|
|
209
318
|
"minify": false,
|
|
210
|
-
"
|
|
211
|
-
"
|
|
212
|
-
"
|
|
319
|
+
"elementsAsIs": false,
|
|
320
|
+
"reservedElements": [],
|
|
321
|
+
"sourceMaps": false,
|
|
322
|
+
"validate": false,
|
|
323
|
+
"nodeModulesAsIs": false,
|
|
324
|
+
"componentsAsIs": false,
|
|
325
|
+
"runtimeAsIs": false,
|
|
326
|
+
"iterationsAsIs": false
|
|
213
327
|
}
|
|
214
328
|
}
|
|
215
329
|
```
|
|
216
330
|
|
|
331
|
+
**Key Options:**
|
|
332
|
+
|
|
333
|
+
- `elementsAsIs: false` — Transform custom elements to divs (default)
|
|
334
|
+
- `reservedElements: []` — Additional element names to reserve (appends to built-in HTML5 elements + "component")
|
|
335
|
+
- `componentsAsIs: false` — Inline components (default) or keep separate for runtime
|
|
336
|
+
- `iterationsAsIs: false` — Optimize iterations (default) or use runtime rendering
|
|
337
|
+
- `runtimeAsIs: false` — Generate manifest (default) or skip for runtime-only
|
|
338
|
+
|
|
217
339
|
**Defaults** (when no config):
|
|
218
340
|
|
|
219
341
|
- `source`: `./`
|
|
@@ -254,6 +376,66 @@ Auto-detects based on lockfiles: `bun.lockb`, `pnpm-lock.yaml`, `yarn.lock`, `pa
|
|
|
254
376
|
**Opt-out:**
|
|
255
377
|
Set `nodeModulesAsIs: true` in config or use `--node-modules-as-is` flag to copy node_modules as-is.
|
|
256
378
|
|
|
379
|
+
### Watch Mode
|
|
380
|
+
|
|
381
|
+
Watch mode enables incremental compilation with intelligent dependency tracking:
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
bunx vibe compile --watch
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Features:
|
|
388
|
+
- **Incremental builds** — Only recompiles changed files (~100ms)
|
|
389
|
+
- **Dependency tracking** — Changes to components trigger recompilation of pages using them
|
|
390
|
+
- **Debounced** — 300ms debounce prevents excessive compilation during rapid changes
|
|
391
|
+
- **Delta output** — First compile shows full output, subsequent compiles show only changes
|
|
392
|
+
|
|
393
|
+
### Component System
|
|
394
|
+
|
|
395
|
+
Components are automatically inlined during compilation with full support for props and slots:
|
|
396
|
+
|
|
397
|
+
```html
|
|
398
|
+
<!-- Source: components/card.html -->
|
|
399
|
+
<div class="card">
|
|
400
|
+
<h2>@[title]</h2>
|
|
401
|
+
<p>@[description]</p>
|
|
402
|
+
<slot></slot>
|
|
403
|
+
</div>
|
|
404
|
+
|
|
405
|
+
<!-- Usage in page -->
|
|
406
|
+
<component src="/components/card.html" title="My Card" description="Card description">
|
|
407
|
+
<p>Slot content</p>
|
|
408
|
+
</component>
|
|
409
|
+
|
|
410
|
+
<!-- Compiled output -->
|
|
411
|
+
<component>
|
|
412
|
+
<div class="card">
|
|
413
|
+
<h2>My Card</h2>
|
|
414
|
+
<p>Card description</p>
|
|
415
|
+
<p>Slot content</p>
|
|
416
|
+
</div>
|
|
417
|
+
</component>
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Custom element syntax:** Components can also use custom element syntax (e.g., `<card>` → auto-converts to `<component src="/components/card.html">`).
|
|
421
|
+
|
|
422
|
+
**Opt-out:** Set `componentsAsIs: true` to keep components as separate files for runtime loading.
|
|
423
|
+
|
|
424
|
+
### Iteration Optimization
|
|
425
|
+
|
|
426
|
+
The compiler generates optimized batch functions for `<!-- each -->` loops, providing 2-3x faster rendering:
|
|
427
|
+
|
|
428
|
+
```html
|
|
429
|
+
<!-- Source -->
|
|
430
|
+
<!-- each items as item, index -->
|
|
431
|
+
<li>@[index]: @[item]</li>
|
|
432
|
+
<!-- /each -->
|
|
433
|
+
|
|
434
|
+
<!-- Compiled to optimized batch function -->
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
**Opt-out:** Set `iterationsAsIs: true` to use runtime rendering for all iterations.
|
|
438
|
+
|
|
257
439
|
### Output Structure
|
|
258
440
|
|
|
259
441
|
Mirrors source structure:
|
|
@@ -271,9 +453,9 @@ src/ compiled/
|
|
|
271
453
|
└── vibe/ └── vibe/
|
|
272
454
|
```
|
|
273
455
|
|
|
274
|
-
###
|
|
456
|
+
### Element Transformation
|
|
275
457
|
|
|
276
|
-
|
|
458
|
+
By default (`elementsAsIs: false`), custom HTML elements are transformed to divs with classes for better HTML validity:
|
|
277
459
|
|
|
278
460
|
```html
|
|
279
461
|
<!-- input -->
|
|
@@ -283,7 +465,23 @@ src/ compiled/
|
|
|
283
465
|
<div class="counter-header">Count</div>
|
|
284
466
|
```
|
|
285
467
|
|
|
286
|
-
|
|
468
|
+
Set `elementsAsIs: true` or use `--elements-as-is` flag to keep custom elements unchanged.
|
|
469
|
+
|
|
470
|
+
**Note:** The `<component>` element is a framework element and is never transformed.
|
|
471
|
+
|
|
472
|
+
### Reserved Element Names
|
|
473
|
+
|
|
474
|
+
The compiler validates component filenames against reserved element names (all HTML5 elements + "component" + your custom list). This prevents confusing bugs where components share names with HTML elements.
|
|
475
|
+
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"vibe-compiler": {
|
|
479
|
+
"reservedElements": ["my-custom-element", "another-reserved-name"]
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Case-sensitive validation:** `nav.html` conflicts with `<nav>` and will error, but `Nav.html` is allowed.
|
|
287
485
|
|
|
288
486
|
### Building Native Binaries
|
|
289
487
|
|
package/boot.js
CHANGED
|
Binary file
|