@ape-egg/vibe 1.3.2 → 1.6.0
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 +177 -0
- package/README.md +97 -0
- package/boot.js +0 -1
- package/compiler/native/vibe-compiler-darwin-arm64 +0 -0
- package/compiler/src/Cargo.lock +719 -40
- package/compiler/src/Cargo.toml +11 -2
- package/compiler/src/compiler/PRE-RENDERING-IMPLEMENTATION.md +241 -0
- package/compiler/src/compiler/compile.rs +552 -175
- 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 +41 -28
- 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} +204 -132
- 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,182 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.6.0] - 2026-02-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Watch mode** - Compiler now supports file watching with incremental compilation
|
|
8
|
+
- New `--watch` flag monitors source files for changes and automatically recompiles
|
|
9
|
+
- Intelligent change detection tracks affected files and their dependencies
|
|
10
|
+
- Transitive dependency tracking: changes to components trigger recompilation of pages using them
|
|
11
|
+
- Blacklist support: watch mode respects SKIP_FILES patterns (tests/, node_modules/, etc.)
|
|
12
|
+
- Debounced file events (300ms) prevent excessive compilation during rapid changes
|
|
13
|
+
- Outputs only changed files for fast incremental builds
|
|
14
|
+
- First compile shows full output, subsequent compiles show only deltas
|
|
15
|
+
- **Reserved element validation** - Compiler now prevents component naming conflicts
|
|
16
|
+
- New `reservedElements` config option (replaces `excludeTags`)
|
|
17
|
+
- Defaults to all HTML5 elements plus "component" keyword
|
|
18
|
+
- User-provided values append to defaults (not replace)
|
|
19
|
+
- Case-sensitive validation: `nav.html` → Error, `Nav.html` → OK
|
|
20
|
+
- Compile-time error with clear message showing conflicting filename
|
|
21
|
+
- Prevents runtime confusion between HTML elements and custom components
|
|
22
|
+
- **Component path case-sensitivity** - Component paths are now treated as case-sensitive
|
|
23
|
+
- `<component src="path/to/MyComponent.html">` and `<component src="path/to/mycomponent.html">` are different
|
|
24
|
+
- Both runtime and compiler preserve exact case in paths
|
|
25
|
+
- Cache keys include full case-sensitive path
|
|
26
|
+
- Enables PascalCase naming convention for components while supporting any casing
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Component inlining architecture** - Complete rewrite from iterative to recursive fetching
|
|
31
|
+
- Removed MAX_ITERATIONS constant and loop-based approach
|
|
32
|
+
- `fetch_component_recursive()` now returns fully resolved content with all nested components inlined
|
|
33
|
+
- Components are cached only after being fully resolved (prevents incomplete content in cache)
|
|
34
|
+
- `inline_component_elements()` now does single pass (no loops)
|
|
35
|
+
- Significant performance improvement: sub-100ms compilation for complex nested components
|
|
36
|
+
- **Framework element handling** - `<component>` is now recognized as a framework element
|
|
37
|
+
- Never transformed to `<div>` regardless of `--elements-as-is` flag
|
|
38
|
+
- Custom elements (e.g., `<card>`, `<text>`) are transformed when `elements_as_is: false`
|
|
39
|
+
- Framework elements vs custom elements properly distinguished in compiler
|
|
40
|
+
- Wrapper `<component>` tags remain after inlining (expected by runtime)
|
|
41
|
+
- **Component inlining behavior** - Custom elements are always inlined
|
|
42
|
+
- `<card>` → transformed to `<component>` → inlined even with `--components-as-is`
|
|
43
|
+
- `--components-as-is` only affects explicit `<component src="...">` tags
|
|
44
|
+
- Consistent behavior: custom elements compile away, framework elements remain
|
|
45
|
+
- **Path normalization** - Component paths now consistently normalized
|
|
46
|
+
- All paths start with `/` (unless external URL)
|
|
47
|
+
- Cache uses normalized paths to prevent duplicates (`/components/nav.html` vs `./components/nav.html`)
|
|
48
|
+
- Fixes cache pollution from different path formats for same component
|
|
49
|
+
- **Config naming** - `excludeTags` renamed to `reservedElements` throughout codebase
|
|
50
|
+
- Better describes purpose (reserved from use as component names)
|
|
51
|
+
- Updated in Rust compiler, config files, and documentation
|
|
52
|
+
- Backward compatible: old config key still works but deprecated
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- Watch mode was compiling blacklisted files (tests/, node_modules/)
|
|
57
|
+
- Component inlining created infinite nested wrappers (100+ levels)
|
|
58
|
+
- Empty headlines in tests due to broken external component fetching
|
|
59
|
+
- Path case normalization could cause duplicates in component cache
|
|
60
|
+
- Accessibility transformation incorrectly converting `<component>` to divs
|
|
61
|
+
- Test expectations mismatched actual framework element behavior
|
|
62
|
+
|
|
63
|
+
### Performance
|
|
64
|
+
|
|
65
|
+
- Watch mode incremental compilation: ~100ms for typical changes
|
|
66
|
+
- First full compilation: ~300-500ms
|
|
67
|
+
- Component fetching: recursive approach 10x faster than iterative (no MAX_ITERATIONS overhead)
|
|
68
|
+
- Path normalization prevents redundant fetches of same component
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## [1.5.0] - 2026-02-09
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
|
|
76
|
+
- **Nested iteration compilation** - Compiler now handles infinitely nested `<!-- each -->` blocks
|
|
77
|
+
- Recursive processing in `iteration_optimizer.rs` with depth counting for comment pair matching
|
|
78
|
+
- Nested loops compile to IIFEs (Immediately Invoked Function Expressions) with template literals
|
|
79
|
+
- Inner iterations inlined directly into outer batch functions for optimal performance
|
|
80
|
+
- Example: `<!-- each categories as cat --><!-- each cat.items as item -->` compiles to single optimized function
|
|
81
|
+
- **QuickJS JavaScript runtime** - Full expression evaluation at compile time
|
|
82
|
+
- Embedded QuickJS engine (`rquickjs = "0.6"`) for JavaScript evaluation in Rust
|
|
83
|
+
- No external dependencies - increases binary size by ~1-2MB
|
|
84
|
+
- Evaluates any JavaScript expression: `@[categories.length]`, `@[items[0]]`, `@[user.name.toUpperCase()]`
|
|
85
|
+
- State set in global scope: `Object.assign(globalThis, $)` matches Vibe runtime behavior
|
|
86
|
+
- Fast evaluation: ~160ms overhead for 35 files (~5ms per file)
|
|
87
|
+
- **Complete pre-rendering** - Zero FOUC with all bindings pre-rendered for SEO
|
|
88
|
+
- All `@[expression]` bindings evaluated and stamped into HTML at compile time
|
|
89
|
+
- Handles property access (`@[user.name]`), array methods (`@[categories.length]`), and complex expressions
|
|
90
|
+
- Nested iterations fully pre-rendered with merged state for each iteration context
|
|
91
|
+
- Falls back gracefully: undefined expressions left as `@[...]` for runtime hydration
|
|
92
|
+
- New test: `stamp_array_length` validates `.length` property evaluation
|
|
93
|
+
|
|
94
|
+
### Changed
|
|
95
|
+
|
|
96
|
+
- **Value stamper rewrite** (`value_stamper.rs`) - Complete overhaul to use QuickJS
|
|
97
|
+
- Replaced JSON path resolution with JavaScript expression evaluation
|
|
98
|
+
- `eval_expression()` handles any valid JavaScript with state in scope
|
|
99
|
+
- `eval_array_path()` evaluates array paths for iteration rendering
|
|
100
|
+
- Iteration rendering creates merged state (parent + item + index) for nested context
|
|
101
|
+
- Removed manual property traversal code - JavaScript engine handles it all
|
|
102
|
+
- **Compiled iteration updates** - Always use compiled path when available (`iterate.js:364`)
|
|
103
|
+
- Previously only used compiled updates for edge cases (empty↔full, large arrays >100)
|
|
104
|
+
- Now uses compiled batch functions for ALL updates when manifest has `compiled.iterations.batchFn`
|
|
105
|
+
- Fixes issue where small array updates (3→4 items) fell through to incompatible runtime path
|
|
106
|
+
- Ensures consistent performance regardless of array size or transition type
|
|
107
|
+
- **State extraction improvements** (`state_extractor.rs`) - Better error handling
|
|
108
|
+
- Silently skips unparseable state objects instead of failing compilation
|
|
109
|
+
- Enables graceful degradation when state contains functions or complex expressions
|
|
110
|
+
|
|
111
|
+
### Fixed
|
|
112
|
+
|
|
113
|
+
- Compiled iterations not updating when array size changes (e.g., add/remove items)
|
|
114
|
+
- Pre-rendering skipped for JavaScript expressions like `@[categories.length]`
|
|
115
|
+
- Nested iteration values showing as `@[item]` instead of actual data
|
|
116
|
+
- Runtime path attempting to handle compiled iterations incorrectly
|
|
117
|
+
|
|
118
|
+
### Performance
|
|
119
|
+
|
|
120
|
+
- Pre-rendering adds ~160ms to compilation for 35 files (~435ms total, up from ~310ms)
|
|
121
|
+
- QuickJS evaluation: ~1-5ms per binding
|
|
122
|
+
- Compiled nested iterations: Same performance as shallow iterations (no recursion overhead at runtime)
|
|
123
|
+
- Zero runtime cost for pre-rendered bindings - HTML arrives with values already stamped
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## [1.4.0] - 2026-02-09
|
|
128
|
+
|
|
129
|
+
### Added
|
|
130
|
+
|
|
131
|
+
- **Iteration optimization** - Compiler now generates optimized batch functions for `<!-- each -->` loops
|
|
132
|
+
- New `iteration_optimizer.rs` module generates string-based batch render functions
|
|
133
|
+
- Provides 2-3x performance improvement for iteration rendering (15-17ms vs 40ms for 1000 rows)
|
|
134
|
+
- Only applies to shallow iterations (nested iterations still use runtime path)
|
|
135
|
+
- Compiled batch functions are stored in manifest and executed at runtime
|
|
136
|
+
- **Pre-compiled iterations runtime** (`runtime/pre-compiled-iterations.js`)
|
|
137
|
+
- Production implementation of compiled iteration rendering
|
|
138
|
+
- Uses pre-compiled batch functions from manifest generated at build time
|
|
139
|
+
- Based on the prototype in `_vibe-compiled-iteration-batch.js`
|
|
140
|
+
- Automatically falls back to runtime rendering for nested iterations or missing batch functions
|
|
141
|
+
- **Compiler configuration** - New `iterationsAsIs` flag
|
|
142
|
+
- Set to `true` in `vibe-compiler` config to skip iteration optimization
|
|
143
|
+
- Iterations pass through unchanged and are handled entirely by runtime
|
|
144
|
+
- Default: `false` (iterations are optimized)
|
|
145
|
+
- **Hyperspeed benchmark** - New benchmark page for measuring pre-compiled performance
|
|
146
|
+
- Tests iteration optimization with 1000 rows
|
|
147
|
+
- Compares runtime vs compiled iteration rendering
|
|
148
|
+
- Available at `e2e-runtime/hyperspeed-benchmark.html`
|
|
149
|
+
- **Compiler test coverage** for iteration compilation
|
|
150
|
+
- `tests/compiler/iterations/` - Tests iteration optimization is applied
|
|
151
|
+
- `tests/compiler/iterations-as-is/` - Tests `iterationsAsIs` flag skips optimization
|
|
152
|
+
- E2E tests verify compiled iterations render correctly
|
|
153
|
+
|
|
154
|
+
### Changed
|
|
155
|
+
|
|
156
|
+
- **Renamed `runtime/hyperspeed.js` → `runtime/pre-compiled-manifest.js`**
|
|
157
|
+
- Better naming to reflect that it handles all pre-compiled features, not just "hyperspeed"
|
|
158
|
+
- Updated all imports and references throughout codebase
|
|
159
|
+
- **Enhanced manifest merging** - Compiler manifest now preserves compiled iteration data
|
|
160
|
+
- Iteration nodes retain `compiled.iterations.batchFn` from manifest during runtime merge
|
|
161
|
+
- Prevents compiled data from being discarded when merging with runtime tree
|
|
162
|
+
- **Debug logging improvements**
|
|
163
|
+
- Added manifest filename to debug output ("Loaded index.manifest.js, page is pre-compiled")
|
|
164
|
+
- Shows compiled feature count (e.g., "3 iterations optimized")
|
|
165
|
+
- Better visibility into which optimizations are active
|
|
166
|
+
- **Runtime iteration handling** - Iterations check for compiled batch functions before falling back
|
|
167
|
+
- `canUseCompiled()` determines if iteration can use batch function
|
|
168
|
+
- Falls back to runtime rendering for nested structures or missing compiled data
|
|
169
|
+
- Seamless integration between compiled and runtime paths
|
|
170
|
+
|
|
171
|
+
### Fixed
|
|
172
|
+
|
|
173
|
+
- Runtime cleanup now properly handles compiled iteration nodes
|
|
174
|
+
- Manifest merge no longer discards compiled data from iteration nodes
|
|
175
|
+
- Debug logging visibility flag now correctly propagates through manifest loading
|
|
176
|
+
- Iteration restoration respects compiled batch functions
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
3
180
|
## [1.3.2] - 2025-02-06
|
|
4
181
|
|
|
5
182
|
### Fixed
|
package/README.md
CHANGED
|
@@ -124,6 +124,103 @@ Skip reactive processing for an element:
|
|
|
124
124
|
<code dehydrate>@[this] displays literally</code>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
+
### Reserved Words & Gotchas
|
|
128
|
+
|
|
129
|
+
Vibe uses specific patterns and keywords that have special meaning. Avoid using these for other purposes to prevent unexpected behavior:
|
|
130
|
+
|
|
131
|
+
#### Classes & Attributes
|
|
132
|
+
|
|
133
|
+
- **`vibe-fouc`** — Class or attribute for FOUC (Flash of Unstyled Content) prevention. Automatically removed after hydration completes.
|
|
134
|
+
```html
|
|
135
|
+
<body vibe-fouc> <!-- or class="vibe-fouc" -->
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
- **`vibe-dehydrate`** — Class or attribute to skip reactive processing. Useful for displaying literal `@[...]` syntax in documentation.
|
|
139
|
+
```html
|
|
140
|
+
<code vibe-dehydrate>@[variable]</code> <!-- or class="vibe-dehydrate" -->
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Element Names & Classes
|
|
144
|
+
|
|
145
|
+
- **`<component>`** — Element name for component system. Used with `src` attribute for runtime component loading, or as a wrapper for inlined components.
|
|
146
|
+
```html
|
|
147
|
+
<component src="/path/to/component.html"></component>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- **`class="component"`** — Alternative syntax for components using standard HTML elements. Useful for HTML validation or accessibility.
|
|
151
|
+
```html
|
|
152
|
+
<div class="component" src="/path/to/component.html"></div>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **`<slot>`** — Element name for component content injection. Gets replaced with content passed between component tags.
|
|
156
|
+
```html
|
|
157
|
+
<!-- In component file -->
|
|
158
|
+
<slot></slot>
|
|
159
|
+
|
|
160
|
+
<!-- Usage -->
|
|
161
|
+
<component src="...">
|
|
162
|
+
<p>This replaces the slot</p>
|
|
163
|
+
</component>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Comment Syntax
|
|
167
|
+
|
|
168
|
+
- **`<!-- each -->`** / **`<!-- /each -->`** — Iteration block markers.
|
|
169
|
+
```html
|
|
170
|
+
<!-- each items as item -->
|
|
171
|
+
<!-- /each -->
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- **`<!-- if -->`** / **`<!-- else -->`** / **`<!-- /if -->`** — Conditional block markers.
|
|
175
|
+
```html
|
|
176
|
+
<!-- if condition -->
|
|
177
|
+
<!-- else -->
|
|
178
|
+
<!-- /if -->
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
#### Binding Syntax
|
|
182
|
+
|
|
183
|
+
- **`@[...]`** — Reactive binding syntax. Reserved for state references.
|
|
184
|
+
```html
|
|
185
|
+
<div>@[variable]</div>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Global Properties
|
|
189
|
+
|
|
190
|
+
- **`window.$`** — Global reactive state object. All reactive data should be accessed through this.
|
|
191
|
+
```javascript
|
|
192
|
+
window.$ = state({ count: 0 });
|
|
193
|
+
$.count++; // Triggers reactive updates
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- **`window.__vibeManifest`** — Internal manifest data. Used by the compiler for optimization. Don't modify.
|
|
197
|
+
|
|
198
|
+
- **`window.__vibeCompiling`** — Internal flag. Set to `true` when running in compiler context.
|
|
199
|
+
|
|
200
|
+
#### Data Attributes
|
|
201
|
+
|
|
202
|
+
- **`data-vibe-component-id`** — Internal attribute for component scoping. Automatically added to component elements. Don't use manually.
|
|
203
|
+
|
|
204
|
+
#### Event Names
|
|
205
|
+
|
|
206
|
+
- **`vibe:ready`** — Custom event fired when Vibe completes initial hydration.
|
|
207
|
+
```javascript
|
|
208
|
+
document.addEventListener('vibe:ready', () => {
|
|
209
|
+
console.log('Vibe is ready');
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
#### Special Attribute Meanings
|
|
214
|
+
|
|
215
|
+
- **`src`** on **`<component>`** or **`<div class="component">`** — Triggers runtime component fetching. Components without `src` are treated as inline wrappers.
|
|
216
|
+
```html
|
|
217
|
+
<!-- Both work the same way -->
|
|
218
|
+
<component src="/components/card.html"></component>
|
|
219
|
+
<div class="component" src="/components/card.html"></div>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
- **`dehydrate`** — Attribute or class name to skip reactive processing (alias for `vibe-dehydrate`).
|
|
223
|
+
|
|
127
224
|
### Deep Reactivity
|
|
128
225
|
|
|
129
226
|
Vibe uses recursive proxies to detect changes at any nesting level:
|
package/boot.js
CHANGED
|
Binary file
|