@hyperfixi/vite-plugin 3.3.0 → 4.0.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/README.md +100 -95
- package/dist/index.cjs +244 -1856
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -130
- package/dist/index.d.ts +36 -130
- package/dist/index.js +243 -1863
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
# @hyperfixi/vite-plugin
|
|
2
2
|
|
|
3
|
-
Zero-config Vite plugin that
|
|
3
|
+
Zero-config Vite plugin that emits a bundle on [`@hyperfixi/engine`](../engine/README.md) registering only the grammar modules your hyperscript uses.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Zero-config**: Just add the plugin and it works
|
|
8
8
|
- **Automatic detection**: Scans HTML, Vue, Svelte, JSX/TSX for `_="..."` attributes
|
|
9
|
-
- **Minimal bundles**:
|
|
9
|
+
- **Minimal bundles**: Registers only the engine modules your commands and blocks need (17.9 KB gzipped for three commands, 34.4 KB for everything)
|
|
10
|
+
- **Upstream's grammar**: The engine is gated by `_hyperscript`'s own test suite, so what works on `hyperfixi-hs.js` works in the generated bundle
|
|
11
|
+
- **Multilingual**: Non-English scripts are translated as the engine reads them (the attribute stays as written)
|
|
10
12
|
- **HMR support**: Re-generates bundle when you add new hyperscript
|
|
11
13
|
- **Framework agnostic**: Works with any Vite-based project
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
14
16
|
|
|
15
17
|
```bash
|
|
16
|
-
npm install @hyperfixi/vite-plugin @hyperfixi/
|
|
18
|
+
npm install @hyperfixi/vite-plugin @hyperfixi/engine
|
|
17
19
|
```
|
|
18
20
|
|
|
19
21
|
## Quick Start
|
|
@@ -29,7 +31,7 @@ export default {
|
|
|
29
31
|
|
|
30
32
|
```javascript
|
|
31
33
|
// main.js
|
|
32
|
-
import 'hyperfixi'; //
|
|
34
|
+
import 'hyperfixi'; // the generated bundle: the engine + your modules
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
```html
|
|
@@ -40,47 +42,44 @@ import 'hyperfixi'; // Auto-generated minimal bundle
|
|
|
40
42
|
## How It Works
|
|
41
43
|
|
|
42
44
|
1. **Scans** your HTML/Vue/Svelte/JSX files for `_="..."` attributes
|
|
43
|
-
2. **Detects** which commands, blocks, and
|
|
44
|
-
3. **
|
|
45
|
+
2. **Detects** which commands, blocks, and expression kinds you use
|
|
46
|
+
3. **Emits** a bundle on [`@hyperfixi/engine`](../engine/README.md) that registers only
|
|
47
|
+
the grammar modules those need — a bundle on the engine is the list passed to
|
|
48
|
+
`register()`, so there is one tier: the modules. The emitted module is a few
|
|
49
|
+
lines; Vite bundles the engine's modules into it.
|
|
45
50
|
4. **Regenerates** on HMR when you add new hyperscript
|
|
46
51
|
|
|
47
|
-
## Compile Mode (Minimal Bundle Size)
|
|
48
|
-
|
|
49
|
-
When bundle size is the priority, use **compile mode** to pre-compile hyperscript to JavaScript at build time:
|
|
50
|
-
|
|
51
52
|
```javascript
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
// What the virtual module looks like for a page using toggle, add and an if block
|
|
54
|
+
import {
|
|
55
|
+
api,
|
|
56
|
+
boot,
|
|
57
|
+
register,
|
|
58
|
+
on,
|
|
59
|
+
conversions,
|
|
60
|
+
add,
|
|
61
|
+
toggle,
|
|
62
|
+
ifCommand,
|
|
63
|
+
toggleElement,
|
|
64
|
+
} from '@hyperfixi/engine';
|
|
65
|
+
register(on, conversions, add, toggle, ifCommand, toggleElement);
|
|
66
|
+
window.hyperfixi = api; // the same object boot() installs as window._hyperscript
|
|
67
|
+
boot();
|
|
68
|
+
export default api;
|
|
55
69
|
```
|
|
56
70
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| Dynamic `execute()` | ✓ | ✗ |
|
|
63
|
-
| Block commands | ✓ | ✗ |
|
|
64
|
-
| Build complexity | Lower | Higher |
|
|
65
|
-
|
|
66
|
-
**When to use compile mode:**
|
|
67
|
-
|
|
68
|
-
- Landing pages with simple interactions (toggles, shows, hides)
|
|
69
|
-
- Performance-critical apps where every KB matters
|
|
70
|
-
- Static sites where hyperscript is just for UI polish
|
|
71
|
+
The engine's parser is upstream `_hyperscript`'s grammar (its vendored test suite
|
|
72
|
+
is the gate), so a generated bundle reads exactly what `hyperfixi-hs.js` reads;
|
|
73
|
+
only the command set differs. Scanning is by word, so a name the engine has no
|
|
74
|
+
module for (a false positive in a string, or a form the engine dropped) selects
|
|
75
|
+
nothing; `debug: true` lists them.
|
|
71
76
|
|
|
72
|
-
|
|
77
|
+
## Compile Mode (removed in 4.0)
|
|
73
78
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
-
|
|
77
|
-
|
|
78
|
-
**Supported commands in compile mode:**
|
|
79
|
-
toggle, add, remove, show, hide, focus, blur, set, get, put, increment, decrement, log, send, trigger, wait
|
|
80
|
-
|
|
81
|
-
**Positional expressions:** next, previous, parent, first, last, closest
|
|
82
|
-
|
|
83
|
-
**Animations:** Use CSS transitions - toggling classes triggers them automatically. No special `transition` command needed.
|
|
79
|
+
`mode: 'compile'` pre-compiled handlers to JavaScript with `@hyperfixi/core`'s hybrid
|
|
80
|
+
parser (~500 bytes for a page of toggles). It was parked with the AOT compiler (owner
|
|
81
|
+
decision 2026-10-03) and left with core's parser in 4.0. Selecting it logs a warning and
|
|
82
|
+
builds the engine-module bundle above, which is the product.
|
|
84
83
|
|
|
85
84
|
## Multilingual & Semantic Parsing
|
|
86
85
|
|
|
@@ -158,40 +157,44 @@ per language, so the final size depends on Vite's tree-shaking; for reference, t
|
|
|
158
157
|
prebuilt standalone semantic bundles range from ~90 KB (no languages) to ~260 KB
|
|
159
158
|
(all 24 languages) gzipped, measured locally — see `docs/BROWSER_BUNDLES.md` in the repo.
|
|
160
159
|
|
|
161
|
-
###
|
|
162
|
-
|
|
163
|
-
```text
|
|
164
|
-
Level 0: Base HybridParser (default)
|
|
165
|
-
↓ semantic: true
|
|
166
|
-
Level 1: + Semantic English
|
|
167
|
-
↓ languages detected/specified
|
|
168
|
-
Level 2: + Regional Semantic Bundle
|
|
169
|
-
↓ grammar: true
|
|
170
|
-
Level 3: + translateHyperscript() (semantic's translate)
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
Each level adds bundle weight; the plugin picks the lowest level that covers the
|
|
174
|
-
features and languages it detects in your source.
|
|
175
|
-
|
|
176
|
-
## htmx v4 reactive / streaming surface
|
|
160
|
+
### How the multilingual bundle works
|
|
177
161
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
162
|
+
Text is the interchange. When semantic parsing is enabled the emitted bundle imports
|
|
163
|
+
`@lokascript/semantic/core` plus one `@lokascript/semantic/languages/<code>` module
|
|
164
|
+
per language and installs a **source transform** on the engine
|
|
165
|
+
(`api.addSourceTransform`): a non-English script is parsed in its language and
|
|
166
|
+
rendered to English as the engine reads it, and the element's attribute stays as
|
|
167
|
+
written. The language comes from `data-lang`, `data-hyperscript-lang`, the nearest
|
|
168
|
+
`lang` ancestor, or the document's `lang`. English scripts pass through untouched.
|
|
169
|
+
|
|
170
|
+
The API gains `translateSource(src, element)` (what the transform does, for one
|
|
171
|
+
script) and, with `grammar: true`, `translateHyperscript(code, from, to)`.
|
|
172
|
+
|
|
173
|
+
Measured 2026-10-03, gzipped: three commands + Spanish is ~209 KB, of which the
|
|
174
|
+
engine is 18 KB — the rest is semantic's parser and the language. Keep the language
|
|
175
|
+
list to what the page uses.
|
|
176
|
+
|
|
177
|
+
## Reactivity, htmx, and streaming
|
|
178
|
+
|
|
179
|
+
`live … end`, `when … changes`, `bind` and `^var` inside `_=` bodies are the
|
|
180
|
+
engine's reactive features: the scanner detects them and the bundle registers the
|
|
181
|
+
engine's `reactivity` and `liveTemplates` modules (+2 KB gzipped). No separate
|
|
182
|
+
bundle, no separate package.
|
|
183
|
+
|
|
184
|
+
htmx is not bundled. Load htmx 4 beside the generated bundle for `hx-get` and
|
|
185
|
+
friends, `hx-sse` / `hx-ws` for streams, and
|
|
186
|
+
[`@lokascript/htmx-adapter`](../htmx-adapter/README.md) for localized attribute
|
|
187
|
+
names (the two stacks in [docs/BROWSER_BUNDLES.md](../../docs/BROWSER_BUNDLES.md)).
|
|
188
|
+
When the scan finds htmx attributes (or `htmx: true` is set) the bundle hands
|
|
189
|
+
swapped-in content to the engine on `htmx:load` / `htmx:afterSettle`. A
|
|
190
|
+
hyperscript-bodied `hx-live` attribute is a `_="live … end"` block on the engine;
|
|
191
|
+
`sse-connect` / `ws-connect` are htmx 4's `hx-sse` / `hx-ws`.
|
|
189
192
|
|
|
190
193
|
## Options
|
|
191
194
|
|
|
192
195
|
```javascript
|
|
193
196
|
hyperfixi({
|
|
194
|
-
// Bundle mode: 'interpret' (default
|
|
197
|
+
// Bundle mode: 'interpret' (default; 'compile' was removed in 4.0, see above)
|
|
195
198
|
mode: 'interpret',
|
|
196
199
|
|
|
197
200
|
// Extra commands to always include (for dynamic hyperscript)
|
|
@@ -201,9 +204,12 @@ hyperfixi({
|
|
|
201
204
|
// Always include positional expressions
|
|
202
205
|
positional: true,
|
|
203
206
|
|
|
204
|
-
//
|
|
207
|
+
// Hand htmx-swapped content to the engine (on by default when hx-* attributes are found)
|
|
205
208
|
htmx: true,
|
|
206
209
|
|
|
210
|
+
// Dev-server bundle: 'everything' (the whole engine, faster rebuilds) or 'auto' (the module list)
|
|
211
|
+
devFallback: 'auto',
|
|
212
|
+
|
|
207
213
|
// Debug logging
|
|
208
214
|
debug: true,
|
|
209
215
|
|
|
@@ -228,18 +234,13 @@ hyperfixi({
|
|
|
228
234
|
|
|
229
235
|
## Detected Features
|
|
230
236
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if, repeat, for, while, fetch
|
|
239
|
-
|
|
240
|
-
### Positional Expressions (6)
|
|
241
|
-
|
|
242
|
-
first, last, next, previous, closest, parent
|
|
237
|
+
The scanner's word list is **derived from the engine** at load: every command and
|
|
238
|
+
feature keyword its modules register (`add`, `call`, `for`, `tell`, `make`, …).
|
|
239
|
+
Blocks: `if`, `repeat`, `for`, `while`, `fetch`. Expression kinds that select the
|
|
240
|
+
engine's optional `expressionsExtra` module: `first`, `last`, `next`, `previous`,
|
|
241
|
+
`closest`, `parent`, `random`, `where`, `sorted by`, `mapped to`, `split by`,
|
|
242
|
+
`joined by`, `some`, `beep!`. Also `new X(…)` (the engine's `construct`
|
|
243
|
+
addition) and `cookies`. `on` and the `as` conversions are always registered.
|
|
243
244
|
|
|
244
245
|
## Virtual Module
|
|
245
246
|
|
|
@@ -262,12 +263,22 @@ When you add new hyperscript to your HTML files, the plugin:
|
|
|
262
263
|
|
|
263
264
|
## Bundle Size Comparison
|
|
264
265
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
|
268
|
-
|
|
|
269
|
-
|
|
|
270
|
-
|
|
|
266
|
+
Measured 2026-10-03 (esbuild, minified, gzipped; `@hyperfixi/engine` 3.3.0):
|
|
267
|
+
|
|
268
|
+
| Usage | Generated size (gzip) |
|
|
269
|
+
| ---------------------------------------------------- | --------------------- |
|
|
270
|
+
| 3 commands (toggle, add, remove) | 17.9 KB |
|
|
271
|
+
| 7 commands (+ show, hide, put, set) | 18.7 KB |
|
|
272
|
+
| 5 commands + `if` / `repeat` | 19.6 KB |
|
|
273
|
+
| 10 commands + `if` / `repeat` / `fetch` + positional | 22.8 KB |
|
|
274
|
+
| + reactivity (`live` / `when` / `bind`) | 20.3 KB |
|
|
275
|
+
| everything (the dev fallback; = `hyperfixi-hs.js`) | 34.4 KB |
|
|
276
|
+
|
|
277
|
+
The engine's fixed cost (tokenizer, parser, the core expression kinds, runtime) is
|
|
278
|
+
13.8 KB, so there is no sub-5 KB tier any more: the 3.x generator's regex "lite"
|
|
279
|
+
parser emitted 3.9 KB for three commands, its hybrid parser 12–16 KB, and any page
|
|
280
|
+
using `fetch` or one of twenty other commands fell back to the 352 KB `hyperfixi.js`.
|
|
281
|
+
What you get in exchange is one grammar, gated by upstream's own test suite.
|
|
271
282
|
|
|
272
283
|
## Edge Cases
|
|
273
284
|
|
|
@@ -297,23 +308,17 @@ hyperfixi({
|
|
|
297
308
|
|
|
298
309
|
## Monorepo Development
|
|
299
310
|
|
|
300
|
-
When developing in the hyperfixi monorepo
|
|
311
|
+
When developing in the hyperfixi monorepo, point the plugin at its source; the
|
|
312
|
+
emitted bundle's `@hyperfixi/engine` import resolves through the workspace
|
|
313
|
+
(build the engine first: `npm run build --prefix packages/engine`):
|
|
301
314
|
|
|
302
315
|
```javascript
|
|
303
316
|
// vite.config.js
|
|
304
317
|
import { hyperfixi } from '../../packages/vite-plugin/src/index.ts';
|
|
305
|
-
import path from 'path';
|
|
306
318
|
|
|
307
319
|
export default {
|
|
308
320
|
plugins: [hyperfixi({ debug: true })],
|
|
309
|
-
|
|
310
|
-
alias: {
|
|
311
|
-
'@hyperfixi/core/parser/hybrid': path.resolve(
|
|
312
|
-
__dirname,
|
|
313
|
-
'../../packages/core/src/parser/hybrid'
|
|
314
|
-
),
|
|
315
|
-
},
|
|
316
|
-
},
|
|
321
|
+
optimizeDeps: { exclude: ['hyperfixi', 'virtual:hyperfixi'] },
|
|
317
322
|
};
|
|
318
323
|
```
|
|
319
324
|
|