@ape-egg/vibe 1.9.0 → 1.9.5
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 +71 -0
- package/README.md +90 -97
- package/ROADMAP.md +6 -12
- package/compiler/native/vibe-compiler-darwin-arm64 +0 -0
- package/compiler/native/vibe-compiler-linux-x64 +0 -0
- package/compiler/src/compiler/PRE-RENDERING-IMPLEMENTATION.md +1 -1
- package/compiler/src/compiler/compile.rs +66 -6
- package/compiler/src/parser/html.rs +7 -1
- package/llms.txt +175 -83
- package/package.json +2 -1
- package/runtime/affected.js +141 -52
- package/runtime/component.js +302 -148
- package/runtime/conditionals.js +45 -3
- package/runtime/constants.js +24 -5
- package/runtime/hydrate.js +35 -21
- package/runtime/index.js +50 -3
- package/runtime/iterate.js +598 -56
- package/runtime/iteration-utils.js +9 -2
- package/runtime/loop-scope.js +157 -0
- package/runtime/parse.js +95 -20
- package/runtime/pre-compiled-iterations.js +12 -0
- package/runtime/state.js +18 -1
- package/runtime/utils.js +39 -2
package/llms.txt
CHANGED
|
@@ -9,9 +9,12 @@ Vibe is a lightweight reactive library that uses Proxy-based state and MutationO
|
|
|
9
9
|
**Key characteristics:**
|
|
10
10
|
- Proxy-based reactive state (`window.$`)
|
|
11
11
|
- Deep reactivity (nested mutations automatically trigger updates)
|
|
12
|
-
- Surgical DOM updates (only affected elements re-render)
|
|
12
|
+
- Surgical DOM updates (only affected elements re-render; idempotent writes skip no-op DOM mutations)
|
|
13
|
+
- State batching (multiple `$.x = y` writes in the same microtask flush as one update)
|
|
13
14
|
- MutationObserver for dynamic element tracking
|
|
14
|
-
- Works with vanilla HTML
|
|
15
|
+
- Works with vanilla HTML — no special file format
|
|
16
|
+
- Component-local state via `component({...})` + `this.X`
|
|
17
|
+
- Component composition via `<component src>` with reactive props (objects/arrays/primitives) and slots
|
|
15
18
|
|
|
16
19
|
## Installation
|
|
17
20
|
|
|
@@ -23,19 +26,21 @@ npm install @ape-egg/vibe
|
|
|
23
26
|
|
|
24
27
|
```html
|
|
25
28
|
<script type="module">
|
|
26
|
-
import
|
|
27
|
-
window.$ =
|
|
29
|
+
import vibe from "@ape-egg/vibe";
|
|
30
|
+
window.$ = vibe({ name: "World", count: 0 });
|
|
28
31
|
</script>
|
|
29
32
|
|
|
30
|
-
<
|
|
31
|
-
<
|
|
33
|
+
<body vibe-fouc>
|
|
34
|
+
<h1>Hello, @[name]!</h1>
|
|
35
|
+
<button onclick="$.count++">Clicked @[count] times</button>
|
|
36
|
+
</body>
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
## Core Syntax
|
|
35
40
|
|
|
36
41
|
### Reactive Bindings
|
|
37
42
|
|
|
38
|
-
Use `@[
|
|
43
|
+
Use `@[expression]` syntax anywhere in HTML or CSS:
|
|
39
44
|
|
|
40
45
|
```html
|
|
41
46
|
<!-- Text content -->
|
|
@@ -44,11 +49,15 @@ Use `@[property]` syntax anywhere in HTML or CSS:
|
|
|
44
49
|
<!-- Expressions -->
|
|
45
50
|
<div>@[firstName + ' ' + lastName]</div>
|
|
46
51
|
<div>@[count * 2]</div>
|
|
52
|
+
<div>@[items.filter(x => x.active).length]</div>
|
|
47
53
|
|
|
48
54
|
<!-- Attributes -->
|
|
49
55
|
<input value="@[inputValue]">
|
|
50
56
|
<button disabled="@[isLoading]">Submit</button>
|
|
51
57
|
|
|
58
|
+
<!-- Attribute names (name bindings) -->
|
|
59
|
+
<icon @[iconName]></icon>
|
|
60
|
+
|
|
52
61
|
<!-- CSS -->
|
|
53
62
|
<style>
|
|
54
63
|
.box { background: @[themeColor]; }
|
|
@@ -65,7 +74,7 @@ State is accessed globally via `window.$`:
|
|
|
65
74
|
// Read
|
|
66
75
|
console.log($.firstName);
|
|
67
76
|
|
|
68
|
-
// Write (triggers re-render)
|
|
77
|
+
// Write (triggers re-render — batched per microtask)
|
|
69
78
|
$.firstName = "John";
|
|
70
79
|
|
|
71
80
|
// Increment
|
|
@@ -97,9 +106,17 @@ With index:
|
|
|
97
106
|
<!-- /each -->
|
|
98
107
|
```
|
|
99
108
|
|
|
109
|
+
The expression after `each` is any JavaScript that returns an array or array-like:
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<!-- each items.filter(x => x.active) as item -->
|
|
113
|
+
<!-- each Array.from({length: 10}, (_, i) => i) as n -->
|
|
114
|
+
<!-- each Object.values(users) as user, i -->
|
|
115
|
+
```
|
|
116
|
+
|
|
100
117
|
### Nested Iteration
|
|
101
118
|
|
|
102
|
-
Use dot paths
|
|
119
|
+
Use dot paths or any expression:
|
|
103
120
|
|
|
104
121
|
```html
|
|
105
122
|
<!-- each categories as category -->
|
|
@@ -122,71 +139,128 @@ Use dot paths for nested arrays:
|
|
|
122
139
|
|
|
123
140
|
Conditionals can be nested inside iterations and vice versa.
|
|
124
141
|
|
|
125
|
-
##
|
|
142
|
+
## Components
|
|
143
|
+
|
|
144
|
+
```html
|
|
145
|
+
<component src="/components/card.html" title="@[pageTitle]" theme="dark">
|
|
146
|
+
<p>This content replaces <slot></slot></p>
|
|
147
|
+
</component>
|
|
148
|
+
```
|
|
126
149
|
|
|
127
|
-
|
|
150
|
+
**Behavior:**
|
|
151
|
+
1. Vibe finds `<component src="...">` elements (also `<div class="component" src="...">`)
|
|
152
|
+
2. Fetches the source HTML
|
|
153
|
+
3. Substitutes props (`@[title]` in the template becomes `@[pageTitle]`)
|
|
154
|
+
4. Inserts slot content (between the tags) into `<slot></slot>`
|
|
155
|
+
5. Removes `src`; the `<component>` wrapper remains as a boundary marker
|
|
128
156
|
|
|
129
|
-
|
|
157
|
+
**Reactive props** (`title="@[pageTitle]"`) keep tracking the parent's state. **Static props** (`theme="dark"`) inline as literals. **Object/array props** through iteration scope (`<component card="@[card]">` inside `<!-- each cards as card -->`) are stashed in an internal registry so child templates can `@[card.name]` or `<!-- each card.abilities as a -->`.
|
|
158
|
+
|
|
159
|
+
**Two-way binding** falls out for free: a child component that writes `$.value = x` in an event handler has that `$.value` rewritten to the parent's bound path, so the parent's state actually updates.
|
|
160
|
+
|
|
161
|
+
**Slot content** that itself contains `<component src>` is also processed recursively.
|
|
162
|
+
|
|
163
|
+
## Component-Local State
|
|
164
|
+
|
|
165
|
+
For state scoped to a single component (form drafts, toggles, derived view-state) instead of global `$`:
|
|
130
166
|
|
|
131
167
|
```html
|
|
132
|
-
|
|
168
|
+
<!-- /components/Counter.html -->
|
|
169
|
+
<script type="module">
|
|
170
|
+
import component from '@ape-egg/vibe/component';
|
|
171
|
+
component({ count: 0, increment() { this.count++; } });
|
|
172
|
+
</script>
|
|
173
|
+
|
|
174
|
+
<button onclick="this.increment()">Clicked @[this.count] times</button>
|
|
133
175
|
```
|
|
134
176
|
|
|
135
|
-
|
|
136
|
-
- Displaying `@[...]` syntax in documentation
|
|
137
|
-
- Static content that shouldn't be reactive
|
|
138
|
-
- Performance optimization for large static sections
|
|
177
|
+
How it works:
|
|
139
178
|
|
|
140
|
-
|
|
179
|
+
1. `component({...})` generates a unique id (e.g. `_c0`) and stores state at `$[id]`
|
|
180
|
+
2. The `<script>` and every following sibling get `data-vibe-component-id="<id>"`
|
|
181
|
+
3. Inside that subtree, `@[this.X.Y]` is rewritten to `@[_c0.X.Y]`; `onclick="this.fn()"` becomes `onclick="$['_c0'].fn()"`; `$.this.x = v` (in event handlers) becomes `$['_c0'].x = v`
|
|
182
|
+
4. When the component leaves the DOM, its bucket is freed automatically
|
|
141
183
|
|
|
142
|
-
|
|
184
|
+
Multi-segment paths, conditionals (`<!-- if this.editing -->`), and iterations (`<!-- each this.items as item -->`) all work. Global `$` and component-local `this.X` coexist within the same template.
|
|
185
|
+
|
|
186
|
+
## Drop-In Components (Standalone Usage)
|
|
187
|
+
|
|
188
|
+
`component()` auto-boots the runtime, so a `<component>` block is a fully self-contained reactive unit. Drop it into any HTML page — no top-level `vibe(...)` call, no build step, no global state setup. Import directly from a CDN:
|
|
143
189
|
|
|
144
190
|
```html
|
|
145
|
-
<
|
|
146
|
-
|
|
191
|
+
<component>
|
|
192
|
+
<script type="module">
|
|
193
|
+
import component from 'https://esm.sh/@ape-egg/vibe/component.js';
|
|
194
|
+
component({ count: 0 });
|
|
195
|
+
</script>
|
|
196
|
+
<button onclick="this.count--">-</button>
|
|
197
|
+
<span>Count: @[this.count]</span>
|
|
198
|
+
<button onclick="this.count++">+</button>
|
|
199
|
+
</component>
|
|
147
200
|
```
|
|
148
201
|
|
|
149
|
-
|
|
202
|
+
Mechanism:
|
|
203
|
+
1. `component({...})` claims the nearest unprocessed `<component>` (or `<div class="component">`) wrapper
|
|
204
|
+
2. It calls `ensureBoot()` from `@ape-egg/vibe/boot`, which initializes `window.$`, parses the DOM, hydrates bindings, and starts the MutationObserver — exactly once per page, even if multiple drop-in blocks call `component()`
|
|
205
|
+
3. `@[this.X]`, `onclick="this.fn()"`, `<!-- if this.X -->`, etc. resolve against that block's bucket
|
|
206
|
+
|
|
207
|
+
Multiple drop-in blocks on the same page each get their own state and run independently. They can still read each other's state via global `$['<id>']` if coordination is needed.
|
|
208
|
+
|
|
209
|
+
This makes vibe usable as a "sprinkle of reactivity" library: paste a snippet into a static site, blog post, CMS-rendered page, or third-party HTML, and it just works.
|
|
210
|
+
|
|
211
|
+
## Lifecycle Hooks
|
|
212
|
+
|
|
213
|
+
```javascript
|
|
214
|
+
$.on('ready', () => {}); // once, after initial parse + hydrate + components mounted
|
|
215
|
+
$.on('afterUpdate', (cur, prev) => {}); // every state change (batched per microtask)
|
|
216
|
+
$.on('afterDomMutation', () => {}); // after every MutationObserver batch
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Also: `await $.ready` resolves after boot, useful when calling code captured `window.$` before vibe finished initializing.
|
|
150
220
|
|
|
151
|
-
|
|
221
|
+
## Special Attributes
|
|
222
|
+
|
|
223
|
+
### vibe-fouc
|
|
224
|
+
|
|
225
|
+
Add to an element (typically `<body>`) to hide it until Vibe's first hydration completes. Vibe removes the attribute when ready.
|
|
152
226
|
|
|
153
227
|
```html
|
|
154
|
-
<
|
|
155
|
-
<input oninput="$.text = this.value">
|
|
156
|
-
<form onsubmit="event.preventDefault(); handleSubmit()">
|
|
228
|
+
<body vibe-fouc>
|
|
157
229
|
```
|
|
158
230
|
|
|
159
|
-
|
|
231
|
+
Pair with `vibe.css` (`<link rel="stylesheet" href="@ape-egg/vibe/vibe.css">`) which targets `[vibe-fouc]` with `visibility: hidden`.
|
|
160
232
|
|
|
161
|
-
###
|
|
233
|
+
### vibe-dehydrate
|
|
162
234
|
|
|
163
|
-
|
|
235
|
+
Skip reactive processing for an element and its children:
|
|
164
236
|
|
|
165
237
|
```html
|
|
166
|
-
<
|
|
167
|
-
.box {
|
|
168
|
-
background: @[backgroundColor];
|
|
169
|
-
color: @[textColor];
|
|
170
|
-
width: @[width]px;
|
|
171
|
-
}
|
|
172
|
-
</style>
|
|
238
|
+
<code vibe-dehydrate>@[this] displays literally, not parsed</code>
|
|
173
239
|
```
|
|
174
240
|
|
|
175
|
-
|
|
241
|
+
Use cases: documenting `@[...]` syntax, large static sections, content that must not be evaluated.
|
|
242
|
+
|
|
243
|
+
### Boolean Attributes
|
|
176
244
|
|
|
177
|
-
|
|
245
|
+
Pure-binding attributes that aren't in the value whitelist (e.g. `disabled`, `checked`, `active`) are added when truthy and removed when falsy:
|
|
178
246
|
|
|
179
247
|
```html
|
|
180
|
-
<
|
|
248
|
+
<button disabled="@[isLoading]">Submit</button>
|
|
249
|
+
<!-- isLoading=false → attribute removed entirely -->
|
|
181
250
|
```
|
|
182
251
|
|
|
183
|
-
|
|
252
|
+
## Events
|
|
253
|
+
|
|
254
|
+
Use standard inline event handlers — they execute against `$` directly:
|
|
184
255
|
|
|
185
256
|
```html
|
|
186
|
-
<
|
|
187
|
-
<
|
|
257
|
+
<button onclick="$.count++">Increment</button>
|
|
258
|
+
<input oninput="$.text = this.value">
|
|
259
|
+
<form onsubmit="event.preventDefault(); handleSubmit()">
|
|
188
260
|
```
|
|
189
261
|
|
|
262
|
+
Inside a component, `this.X` references the component's bucket (rewritten at parse time); `this.value`, `this.checked`, `this.dataset` etc. still reach the DOM element since DOM properties are preserved.
|
|
263
|
+
|
|
190
264
|
## Dynamic Elements
|
|
191
265
|
|
|
192
266
|
Elements added via JavaScript are automatically hydrated through MutationObserver:
|
|
@@ -200,33 +274,47 @@ document.body.appendChild(div);
|
|
|
200
274
|
|
|
201
275
|
## API Reference
|
|
202
276
|
|
|
203
|
-
### `
|
|
277
|
+
### `vibe(initialState, config?)`
|
|
204
278
|
|
|
205
|
-
|
|
279
|
+
Initializes the framework and returns the reactive state proxy.
|
|
206
280
|
|
|
207
281
|
```javascript
|
|
208
|
-
import
|
|
282
|
+
import vibe from "@ape-egg/vibe";
|
|
209
283
|
|
|
210
|
-
window.$ =
|
|
284
|
+
window.$ = vibe(
|
|
211
285
|
{ count: 0, user: { name: "Alice" } },
|
|
212
|
-
|
|
213
|
-
console.log("State updated:", newState);
|
|
214
|
-
}
|
|
286
|
+
{ debug: false }
|
|
215
287
|
);
|
|
216
288
|
```
|
|
217
289
|
|
|
218
290
|
**Parameters:**
|
|
219
|
-
- `initialState`
|
|
220
|
-
- `
|
|
291
|
+
- `initialState` — object containing initial state values
|
|
292
|
+
- `config` — optional object. Currently supports `{ debug: boolean }`. A third positional argument can pass a target selector (defaults to `body`).
|
|
293
|
+
|
|
294
|
+
**Returns:** Reactive proxy. Assign it to `window.$` so inline event handlers and bindings can find it.
|
|
295
|
+
|
|
296
|
+
### `component(initialState)`
|
|
297
|
+
|
|
298
|
+
Imported from `@ape-egg/vibe/component`. Registers a component-local state bucket; called from inside a `<script type="module">` in a component file. See [Component-Local State](#component-local-state).
|
|
221
299
|
|
|
222
|
-
|
|
300
|
+
### `$.on(event, callback)`
|
|
223
301
|
|
|
224
|
-
|
|
302
|
+
Register a lifecycle listener. Events: `'ready'`, `'afterUpdate'`, `'afterDomMutation'`. Listeners registered before boot are queued and replayed once vibe is ready.
|
|
303
|
+
|
|
304
|
+
### `$.ready`
|
|
305
|
+
|
|
306
|
+
A Promise that resolves once vibe has finished initial parse + hydrate + component loading.
|
|
307
|
+
|
|
308
|
+
### `$.reconcile(el, html)` and `$.renderComponent(rawHtml, props, slot, opts)` (advanced)
|
|
309
|
+
|
|
310
|
+
Subtree reconciliation primitives used by `@ape-egg/vite-plugin-vibe` for surgical HMR. `$.reconcile` diffs `el`'s children against fresh `html` while preserving DOM identity, focus, and selection; vibe-managed regions (iterations, conditionals, components, slot pairs) are treated as opaque. Treat these as plumbing — shape may evolve.
|
|
311
|
+
|
|
312
|
+
## Scoped Variables in Iterations
|
|
225
313
|
|
|
226
314
|
Inside `<!-- each -->` blocks, these variables are available:
|
|
227
|
-
- `item` (or custom name)
|
|
228
|
-
- `index` (or custom name)
|
|
229
|
-
- Parent state remains accessible via `$`
|
|
315
|
+
- `item` (or custom name) — current array element
|
|
316
|
+
- `index` (or custom name) — current index
|
|
317
|
+
- Parent state remains accessible via `$` and via free identifiers (e.g. `tutorialProgress`)
|
|
230
318
|
|
|
231
319
|
```html
|
|
232
320
|
<!-- each users as user, i -->
|
|
@@ -236,7 +324,7 @@ Inside `<!-- each -->` blocks, these variables are available:
|
|
|
236
324
|
|
|
237
325
|
### Scoped State (Internal)
|
|
238
326
|
|
|
239
|
-
Each iteration instance stores a `scopedState`
|
|
327
|
+
Each iteration instance stores a `scopedState` Proxy that combines local variables (`item`, `index`) with global state. This lets bindings inside iterations react to global state changes:
|
|
240
328
|
|
|
241
329
|
```html
|
|
242
330
|
<!-- each menuItems as item -->
|
|
@@ -246,50 +334,50 @@ Each iteration instance stores a `scopedState` - a Proxy wrapper that provides a
|
|
|
246
334
|
<!-- /each -->
|
|
247
335
|
```
|
|
248
336
|
|
|
249
|
-
When `tutorialProgress` changes,
|
|
250
|
-
1. Finds affected elements inside iteration instances
|
|
251
|
-
2. Uses that instance's `scopedState` for evaluation
|
|
252
|
-
3. Can access both `item` (local) and `tutorialProgress` (global)
|
|
253
|
-
4. Updates only the affected elements without re-rendering the entire iteration
|
|
337
|
+
When `tutorialProgress` changes, vibe finds affected elements inside iteration instances, evaluates against that instance's `scopedState`, and updates only the changed elements without re-rendering the whole list.
|
|
254
338
|
|
|
255
339
|
## Architecture
|
|
256
340
|
|
|
257
|
-
Vibe consists of these core modules:
|
|
341
|
+
Vibe consists of these core runtime modules (in `runtime/`):
|
|
258
342
|
|
|
259
|
-
- **state.js**
|
|
260
|
-
- **parse.js**
|
|
261
|
-
- **
|
|
262
|
-
- **hydrate.js**
|
|
263
|
-
- **affected.js**
|
|
264
|
-
- **iterate.js**
|
|
265
|
-
- **conditionals.js**
|
|
343
|
+
- **state.js** — Proxy-based reactive state, recursive proxies for deep reactivity, batched flush via `queueMicrotask`
|
|
344
|
+
- **parse.js** — DOM parser that finds `@[...]` bindings, iteration/conditional comments, and `<component src>` elements
|
|
345
|
+
- **manifest.js** — Maps DOM elements to parsed-tree nodes (was `link.js` in older versions)
|
|
346
|
+
- **hydrate.js** — Updates DOM with current state values; idempotent (skips no-op writes)
|
|
347
|
+
- **affected.js** — Determines which bindings need re-evaluation when state changes
|
|
348
|
+
- **iterate.js** — Array rendering with diffing; bulk-replacement fast path; iteration-prop registry for non-primitive component props
|
|
349
|
+
- **conditionals.js** — Conditional block rendering; preserves both branches in the manifest for reactive switching
|
|
350
|
+
- **component.js** — `<component src>` fetching, prop substitution, slot inlining, component-local state setup, `this.X` rewriting
|
|
351
|
+
- **reconcile.js** — Subtree reconciliation primitive (`$.reconcile`)
|
|
352
|
+
- **cleanup.js** — `vibe-fouc` release once a subtree is fully processed
|
|
266
353
|
|
|
267
354
|
## How It Works
|
|
268
355
|
|
|
269
356
|
```
|
|
270
|
-
1.
|
|
271
|
-
2. parse.js scans DOM for @[...], <!-- each -->, <!-- if
|
|
272
|
-
3.
|
|
357
|
+
1. vibe(initialState) creates the Proxy and starts the runtime
|
|
358
|
+
2. parse.js scans DOM for @[...], <!-- each -->, <!-- if -->, <component src>
|
|
359
|
+
3. manifest.js maps elements → parsed tree
|
|
273
360
|
4. hydrate.js replaces bindings with values
|
|
274
361
|
5. iterate.js renders <!-- each --> loops
|
|
275
362
|
6. conditionals.js renders <!-- if --> blocks
|
|
276
|
-
7.
|
|
277
|
-
8.
|
|
363
|
+
7. component.js fetches <component src> templates, substitutes props, inlines slots
|
|
364
|
+
8. MutationObserver watches for new/removed elements; affected.js + hydrate.js handle state changes
|
|
278
365
|
```
|
|
279
366
|
|
|
280
367
|
## Current Limitations
|
|
281
368
|
|
|
282
|
-
- **No computed values**:
|
|
283
|
-
- **
|
|
284
|
-
- **
|
|
369
|
+
- **No computed values primitive**: derived state can be done with `Object.defineProperty($, 'x', { get })` or with `afterUpdate` listeners; a first-class `computed` API isn't shipped
|
|
370
|
+
- **Expression security**: `new Function()` evaluation — don't bind untrusted input
|
|
371
|
+
- **HTML binding**: `@[expr]` always sets `textContent` (escape-safe). A first-class opt-in for trusted HTML is planned but not finalized
|
|
285
372
|
|
|
286
373
|
## Best Practices
|
|
287
374
|
|
|
288
|
-
1. **Initialize state
|
|
289
|
-
2. **
|
|
290
|
-
3. **
|
|
291
|
-
4. **
|
|
292
|
-
5. **
|
|
375
|
+
1. **Initialize state in `<head>`** before reactive elements; pair with `vibe-fouc` on `<body>`
|
|
376
|
+
2. **Mutate freely** — deep reactivity means `$.user.name = "New"` just works; no spread operators needed
|
|
377
|
+
3. **Use lifecycle hooks instead of `setTimeout` / `requestAnimationFrame`** when you need to wait for vibe to finish work
|
|
378
|
+
4. **Use `component({...})` for state that's local to one piece of UI** (form draft, toggle); keep cross-cutting state on global `$`
|
|
379
|
+
5. **Use `vibe-dehydrate` when you need to display `@[...]` literally** (docs, code examples)
|
|
380
|
+
6. **Keep expressions simple** — complex logic belongs in JavaScript; templates should read like HTML
|
|
293
381
|
|
|
294
382
|
## Browser Support
|
|
295
383
|
|
|
@@ -298,6 +386,10 @@ Modern browsers with:
|
|
|
298
386
|
- MutationObserver
|
|
299
387
|
- ES Modules
|
|
300
388
|
|
|
389
|
+
## Related Packages
|
|
390
|
+
|
|
391
|
+
- **`@ape-egg/vite-plugin-vibe`** — Vite plugin with surgical component HMR (template-only edits reconcile in place; script edits re-mount)
|
|
392
|
+
|
|
301
393
|
## Resources
|
|
302
394
|
|
|
303
395
|
- **Homepage**: https://vibe.korte.kim
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ape-egg/vibe",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Runtime-first reactivity with optional compiler",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"homepage": "https://vibe.korte.kim",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./index.js",
|
|
10
|
+
"./boot": "./boot.js",
|
|
10
11
|
"./component": "./component.js",
|
|
11
12
|
"./runtime": "./runtime/index.js",
|
|
12
13
|
"./compiler": "./compiler/bin/vibe-compile.js"
|