@hyperfixi/behaviors 3.3.0 → 4.0.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 +162 -0
- package/README.md +29 -9
- package/dist/all.browser.global.js +45 -100
- package/dist/all.browser.global.js.map +1 -1
- package/dist/autodismiss.browser.global.js +5 -11
- package/dist/autodismiss.browser.global.js.map +1 -1
- package/dist/behaviors/autodismiss.cjs +19 -22
- package/dist/behaviors/autodismiss.cjs.map +1 -1
- package/dist/behaviors/autodismiss.d.cts +4 -4
- package/dist/behaviors/autodismiss.d.ts +4 -4
- package/dist/behaviors/autodismiss.js +3 -3
- package/dist/behaviors/clickoutside.cjs +19 -18
- package/dist/behaviors/clickoutside.cjs.map +1 -1
- package/dist/behaviors/clickoutside.d.cts +4 -4
- package/dist/behaviors/clickoutside.d.ts +4 -4
- package/dist/behaviors/clickoutside.js +3 -3
- package/dist/behaviors/clipboard.cjs +18 -19
- package/dist/behaviors/clipboard.cjs.map +1 -1
- package/dist/behaviors/clipboard.d.cts +4 -4
- package/dist/behaviors/clipboard.d.ts +4 -4
- package/dist/behaviors/clipboard.js +3 -3
- package/dist/behaviors/draggable.cjs +20 -25
- package/dist/behaviors/draggable.cjs.map +1 -1
- package/dist/behaviors/draggable.d.cts +4 -4
- package/dist/behaviors/draggable.d.ts +4 -4
- package/dist/behaviors/draggable.js +3 -3
- package/dist/behaviors/focustrap.cjs +18 -19
- package/dist/behaviors/focustrap.cjs.map +1 -1
- package/dist/behaviors/focustrap.d.cts +4 -4
- package/dist/behaviors/focustrap.d.ts +4 -4
- package/dist/behaviors/focustrap.js +3 -3
- package/dist/behaviors/removable.cjs +18 -21
- package/dist/behaviors/removable.cjs.map +1 -1
- package/dist/behaviors/removable.d.cts +4 -3
- package/dist/behaviors/removable.d.ts +4 -3
- package/dist/behaviors/removable.js +3 -3
- package/dist/behaviors/resizable.cjs +19 -19
- package/dist/behaviors/resizable.cjs.map +1 -1
- package/dist/behaviors/resizable.d.cts +4 -4
- package/dist/behaviors/resizable.d.ts +4 -4
- package/dist/behaviors/resizable.js +3 -3
- package/dist/behaviors/scrollreveal.cjs +19 -22
- package/dist/behaviors/scrollreveal.cjs.map +1 -1
- package/dist/behaviors/scrollreveal.d.cts +4 -4
- package/dist/behaviors/scrollreveal.d.ts +4 -4
- package/dist/behaviors/scrollreveal.js +3 -3
- package/dist/behaviors/sortable.cjs +19 -20
- package/dist/behaviors/sortable.cjs.map +1 -1
- package/dist/behaviors/sortable.d.cts +4 -4
- package/dist/behaviors/sortable.d.ts +4 -4
- package/dist/behaviors/sortable.js +3 -3
- package/dist/behaviors/tabs.cjs +20 -25
- package/dist/behaviors/tabs.cjs.map +1 -1
- package/dist/behaviors/tabs.d.cts +4 -4
- package/dist/behaviors/tabs.d.ts +4 -4
- package/dist/behaviors/tabs.js +3 -3
- package/dist/behaviors/toggleable.cjs +25 -26
- package/dist/behaviors/toggleable.cjs.map +1 -1
- package/dist/behaviors/toggleable.d.cts +4 -4
- package/dist/behaviors/toggleable.d.ts +4 -4
- package/dist/behaviors/toggleable.js +3 -3
- package/dist/chunk-2GIS4DCY.js +30 -0
- package/dist/chunk-2GIS4DCY.js.map +1 -0
- package/dist/chunk-3BCBZR6R.js +30 -0
- package/dist/chunk-3BCBZR6R.js.map +1 -0
- package/dist/chunk-4YUIDZAO.js +30 -0
- package/dist/chunk-4YUIDZAO.js.map +1 -0
- package/dist/{chunk-XYZ7FOXJ.js → chunk-AQCOK5J5.js} +10 -14
- package/dist/chunk-AQCOK5J5.js.map +1 -0
- package/dist/chunk-ATGHQQC7.js +30 -0
- package/dist/chunk-ATGHQQC7.js.map +1 -0
- package/dist/{chunk-HQDYH45I.js → chunk-CWLAXLWR.js} +5 -13
- package/dist/chunk-CWLAXLWR.js.map +1 -0
- package/dist/chunk-DMWN52SV.js +30 -0
- package/dist/chunk-DMWN52SV.js.map +1 -0
- package/dist/{chunk-PDMOOWFW.js → chunk-EIVPVTUI.js} +4 -8
- package/dist/{chunk-PDMOOWFW.js.map → chunk-EIVPVTUI.js.map} +1 -1
- package/dist/chunk-HHTEMPIT.js +30 -0
- package/dist/chunk-HHTEMPIT.js.map +1 -0
- package/dist/{chunk-26IX7QU7.js → chunk-HJESSMKB.js} +4 -6
- package/dist/{chunk-26IX7QU7.js.map → chunk-HJESSMKB.js.map} +1 -1
- package/dist/{chunk-5S7WN3ZQ.js → chunk-IFAH652L.js} +4 -7
- package/dist/chunk-IFAH652L.js.map +1 -0
- package/dist/chunk-IUGJG4RA.js +30 -0
- package/dist/chunk-IUGJG4RA.js.map +1 -0
- package/dist/{chunk-ZR66E3T6.js → chunk-JNLVXPHR.js} +13 -13
- package/dist/chunk-KEZEGPEX.js +30 -0
- package/dist/chunk-KEZEGPEX.js.map +1 -0
- package/dist/{chunk-66U2RSYJ.js → chunk-KP4GNXYS.js} +4 -10
- package/dist/chunk-KP4GNXYS.js.map +1 -0
- package/dist/chunk-KXQMCN4O.js +30 -0
- package/dist/chunk-KXQMCN4O.js.map +1 -0
- package/dist/{chunk-YXS27XM6.js → chunk-KYBOZ7C4.js} +3 -7
- package/dist/chunk-KYBOZ7C4.js.map +1 -0
- package/dist/chunk-LBWM6TTU.js +30 -0
- package/dist/chunk-LBWM6TTU.js.map +1 -0
- package/dist/{chunk-3DVDS7CT.js → chunk-LCDONZBX.js} +5 -5
- package/dist/chunk-LCDONZBX.js.map +1 -0
- package/dist/{chunk-OJ3YWO3W.js → chunk-NE76IBV2.js} +3 -7
- package/dist/chunk-NE76IBV2.js.map +1 -0
- package/dist/{chunk-HMU342XE.js → chunk-PVO6TZCZ.js} +3 -9
- package/dist/{chunk-HMU342XE.js.map → chunk-PVO6TZCZ.js.map} +1 -1
- package/dist/{chunk-URZGNPTQ.js → chunk-RILYRQ72.js} +4 -10
- package/dist/chunk-RILYRQ72.js.map +1 -0
- package/dist/{chunk-FBQ3X3UY.js → chunk-U4QMFVAM.js} +5 -13
- package/dist/chunk-U4QMFVAM.js.map +1 -0
- package/dist/chunk-VWDTOSE3.js +26 -0
- package/dist/chunk-VWDTOSE3.js.map +1 -0
- package/dist/chunk-YRQBU2OW.js +30 -0
- package/dist/chunk-YRQBU2OW.js.map +1 -0
- package/dist/clickoutside.browser.global.js +5 -7
- package/dist/clickoutside.browser.global.js.map +1 -1
- package/dist/clipboard.browser.global.js +4 -8
- package/dist/clipboard.browser.global.js.map +1 -1
- package/dist/core.browser.global.js +13 -25
- package/dist/core.browser.global.js.map +1 -1
- package/dist/draggable.browser.global.js +5 -13
- package/dist/draggable.browser.global.js.map +1 -1
- package/dist/focustrap.browser.global.js +4 -8
- package/dist/focustrap.browser.global.js.map +1 -1
- package/dist/index.cjs +96 -271
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +42 -55
- package/dist/index.js.map +1 -1
- package/dist/loaders.cjs +75 -237
- package/dist/loaders.cjs.map +1 -1
- package/dist/loaders.js +13 -13
- package/dist/registry.cjs +4 -4
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.d.cts +5 -6
- package/dist/registry.d.ts +5 -6
- package/dist/registry.js +1 -1
- package/dist/removable.browser.global.js +3 -9
- package/dist/removable.browser.global.js.map +1 -1
- package/dist/resizable.browser.global.js +4 -7
- package/dist/resizable.browser.global.js.map +1 -1
- package/dist/resolver.browser.global.js +45 -100
- package/dist/resolver.browser.global.js.map +1 -1
- package/dist/schemas/index.cjs +38 -93
- package/dist/schemas/index.cjs.map +1 -1
- package/dist/schemas/index.d.cts +2 -2
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +11 -11
- package/dist/schemas/index.js.map +1 -1
- package/dist/scrollreveal.browser.global.js +5 -11
- package/dist/scrollreveal.browser.global.js.map +1 -1
- package/dist/sortable.browser.global.js +5 -9
- package/dist/sortable.browser.global.js.map +1 -1
- package/dist/tabs.browser.global.js +6 -14
- package/dist/tabs.browser.global.js.map +1 -1
- package/dist/toggleable.browser.global.js +9 -13
- package/dist/toggleable.browser.global.js.map +1 -1
- package/dist/{types-DCCtVQS5.d.cts → types-CbA4L8XJ.d.cts} +16 -23
- package/dist/{types-DCCtVQS5.d.ts → types-CbA4L8XJ.d.ts} +16 -23
- package/package.json +5 -5
- package/src/behavior-resolver.ts +24 -56
- package/src/behaviors/autodismiss.test.ts +12 -20
- package/src/behaviors/autodismiss.ts +8 -23
- package/src/behaviors/clickoutside.test.ts +13 -21
- package/src/behaviors/clickoutside.ts +8 -23
- package/src/behaviors/clipboard.test.ts +12 -34
- package/src/behaviors/clipboard.ts +8 -23
- package/src/behaviors/curated-runtime.test.ts +22 -24
- package/src/behaviors/draggable.ts +10 -24
- package/src/behaviors/experimental-runtime.test.ts +19 -18
- package/src/behaviors/focustrap.test.ts +12 -20
- package/src/behaviors/focustrap.ts +8 -23
- package/src/behaviors/integration.test.ts +19 -54
- package/src/behaviors/optional-runtime.test.ts +17 -22
- package/src/behaviors/removable.ts +6 -20
- package/src/behaviors/resizable.ts +9 -24
- package/src/behaviors/scrollreveal.test.ts +13 -21
- package/src/behaviors/scrollreveal.ts +8 -23
- package/src/behaviors/sortable.ts +7 -22
- package/src/behaviors/tabs.test.ts +12 -34
- package/src/behaviors/tabs.ts +8 -23
- package/src/behaviors/toggleable.ts +10 -26
- package/src/browser-resolver-bundle.ts +20 -30
- package/src/core-bundle.ts +11 -11
- package/src/index.test.ts +2 -2
- package/src/index.ts +30 -47
- package/src/registry.test.ts +9 -34
- package/src/registry.ts +7 -11
- package/src/schemas/autodismiss.schema.ts +3 -9
- package/src/schemas/clickoutside.schema.ts +3 -5
- package/src/schemas/clipboard.schema.ts +2 -6
- package/src/schemas/draggable.schema.ts +4 -12
- package/src/schemas/focustrap.schema.ts +2 -6
- package/src/schemas/index.ts +2 -1
- package/src/schemas/removable.schema.ts +2 -8
- package/src/schemas/resizable.schema.ts +3 -6
- package/src/schemas/scrollreveal.schema.ts +3 -9
- package/src/schemas/sortable.schema.ts +3 -7
- package/src/schemas/tabs.schema.ts +4 -12
- package/src/schemas/toggleable.schema.ts +10 -13
- package/src/schemas/types.ts +37 -30
- package/dist/chunk-2HUF6RMI.js +0 -40
- package/dist/chunk-2HUF6RMI.js.map +0 -1
- package/dist/chunk-3DVDS7CT.js.map +0 -1
- package/dist/chunk-5S7WN3ZQ.js.map +0 -1
- package/dist/chunk-66U2RSYJ.js.map +0 -1
- package/dist/chunk-6TJXDCAQ.js +0 -11
- package/dist/chunk-6TJXDCAQ.js.map +0 -1
- package/dist/chunk-7TPDLB7W.js +0 -40
- package/dist/chunk-7TPDLB7W.js.map +0 -1
- package/dist/chunk-CR3J7VV6.js +0 -40
- package/dist/chunk-CR3J7VV6.js.map +0 -1
- package/dist/chunk-EDBG2F57.js +0 -40
- package/dist/chunk-EDBG2F57.js.map +0 -1
- package/dist/chunk-FBQ3X3UY.js.map +0 -1
- package/dist/chunk-HQDYH45I.js.map +0 -1
- package/dist/chunk-HX663BJ4.js +0 -40
- package/dist/chunk-HX663BJ4.js.map +0 -1
- package/dist/chunk-KROW43CG.js +0 -40
- package/dist/chunk-KROW43CG.js.map +0 -1
- package/dist/chunk-L52AGCMP.js +0 -40
- package/dist/chunk-L52AGCMP.js.map +0 -1
- package/dist/chunk-MTI5PSRH.js +0 -40
- package/dist/chunk-MTI5PSRH.js.map +0 -1
- package/dist/chunk-OJ3YWO3W.js.map +0 -1
- package/dist/chunk-ORBJ7MRW.js +0 -40
- package/dist/chunk-ORBJ7MRW.js.map +0 -1
- package/dist/chunk-SLSCZV4A.js +0 -40
- package/dist/chunk-SLSCZV4A.js.map +0 -1
- package/dist/chunk-URZGNPTQ.js.map +0 -1
- package/dist/chunk-WKBRZGGL.js +0 -40
- package/dist/chunk-WKBRZGGL.js.map +0 -1
- package/dist/chunk-XYZ7FOXJ.js.map +0 -1
- package/dist/chunk-YXS27XM6.js.map +0 -1
- /package/dist/{chunk-ZR66E3T6.js.map → chunk-JNLVXPHR.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,168 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [4.0.0] - 2026-10-04
|
|
11
|
+
|
|
12
|
+
`@hyperfixi/core`'s own hyperscript engine is gone: its root re-exports `@hyperfixi/engine`, and
|
|
13
|
+
its `hyperfixi.js` is the engine's 34 KB script-tag bundle where core's ~352 KB bundle used to be.
|
|
14
|
+
The engine follows upstream `_hyperscript`'s grammar and is gated by upstream's own test suite, so
|
|
15
|
+
scripts in core-only syntax need upstream's spelling (two additions stay: `new X()` and
|
|
16
|
+
`toggle <element>`). Core's other bundles, its htmx layer, the core-era plugin packages and the
|
|
17
|
+
AOT compiler retire: htmx 4 or fixi supply hypermedia attributes beside the engine, and
|
|
18
|
+
`@lokascript/hyperscript-adapter` runs hyperscript written in other languages. Every package moves
|
|
19
|
+
to 4.0.0 together. Everything under **Removed** is breaking, as is each **Changed** item marked ⚠;
|
|
20
|
+
[MIGRATION.md](MIGRATION.md) names each replacement.
|
|
21
|
+
|
|
22
|
+
### Removed
|
|
23
|
+
|
|
24
|
+
- **Core's engine and its API** (#1368). These root exports had no engine counterpart:
|
|
25
|
+
`hyperscript` (`compile`, `compileSync`, `compileAsync`, `eval`, `validate`), `lokascript`,
|
|
26
|
+
`Runtime`, `RuntimeBase`, `createContext` and the element-scope helpers, `installPlugin`,
|
|
27
|
+
`getParserExtensionRegistry`, `setGlobal`, `DebugController`, `validatePartialContent` and its
|
|
28
|
+
helpers, `fromCoreAST` / `toCoreAST`. `parse` is now the engine's. The root is ESM-only, like the
|
|
29
|
+
engine: `dist/index.cjs` and the UMD `dist/index.min.js` (`LokaScriptCore`) are gone, though the
|
|
30
|
+
kept subpaths still ship CommonJS.
|
|
31
|
+
- **21 of core's 29 entry points**: `/commands`, `/expressions`, `/parser/*`, `/behaviors`,
|
|
32
|
+
`/bundle-generator`, `/registry/*`, `/lse`, and `/browser/` `hybrid-complete`, `hybrid-hx`,
|
|
33
|
+
`hybrid-hx-v4`, `multilingual`, `modular` (#1343–#1368). Instead of `/commands`, import the
|
|
34
|
+
grammar modules from the root: `import { toggle } from '@hyperfixi/core'`.
|
|
35
|
+
- **Core's browser bundles** (#1348, #1350, #1352, #1368): `hyperfixi-hx.js`,
|
|
36
|
+
`hyperfixi-hx-v4.js`, `hyperfixi-hybrid-complete.js`, `hyperfixi-multilingual.js`,
|
|
37
|
+
`hyperfixi-classic-i18n.js` and the code-split `hyperfixi.mjs`, plus every alias
|
|
38
|
+
(`hyperfixi-browser.js`, `hyperfixi-hybrid-hx.js`, each `lokascript-*.js`). Only
|
|
39
|
+
`hyperfixi.js` remains. CDN URLs pinned to 3.x keep working.
|
|
40
|
+
- **Core's embedded htmx layer** (#1342, #1348, #1350): `hx-*` and fixi `fx-*` on core's runtime,
|
|
41
|
+
`hx-live`, `sse-connect` / `sse-swap`, `ws-connect` / `ws-send`. Load htmx 4 or fixi beside the
|
|
42
|
+
engine. `hx-live` becomes the engine's `live` block, and SSE and WebSockets are htmx 4's
|
|
43
|
+
`hx-sse` / `hx-ws`.
|
|
44
|
+
- **Core-only members of `window.hyperfixi`**: `compile`, `compileSync`, `execute`, `setLocale`,
|
|
45
|
+
`evalLSENode`, `debugControl`, `semanticDebug`, the `hyperfixi:semantic-parse` event,
|
|
46
|
+
`hyperfixi:debug` logging, `_hyperscript.behaviors.resolve`, and the deprecated
|
|
47
|
+
`window.lokascript` (#1352, #1355).
|
|
48
|
+
- **Core-only hyperscript syntax** (#1346, #1363, #1365). The engine rejects `has` / `have`,
|
|
49
|
+
`prepend`, `copy`, `push url` / `replace url`, `process partials`, the `pseudo` keyword, prefix
|
|
50
|
+
`unless`, bare `beep`, `a ? b : c`, core's `swap <strategy> of X with Y`, `set @a to v on X`,
|
|
51
|
+
`.debounce(n)` / `.throttle(n)`, `my?.x` and `tell X to …`. A few forms still parse but no longer
|
|
52
|
+
do what they did, such as `toggle .a on this` and `go forward`. MIGRATION.md gives each form's
|
|
53
|
+
upstream spelling. The multilingual reader still accepts them all.
|
|
54
|
+
- **`@hyperfixi/core/multilingual`'s class API** (#1345, #1368): `MultilingualHyperscript` (with
|
|
55
|
+
`parseToAST`, `getAllTranslations`, …), `getMultilingual`, `multilingual`, `LanguageInfo`,
|
|
56
|
+
`schemaRoleInferrer`. The entry is three async functions: `parse`, `render`, `translate`.
|
|
57
|
+
- **The AOT compiler** (#1364). Its output ran only on a runtime that was never published.
|
|
58
|
+
`@lokascript/compilation-service` loses `compile()`, `POST /compile`, `CompileResponse`, the
|
|
59
|
+
compile cache (`SemanticCache`, `getCacheStats`, `clearCache`, `/cache`), `generateTests`'
|
|
60
|
+
`executionMode` and `generate()`'s `'js'` target. `generate()` now requires `target`
|
|
61
|
+
(`react` | `vue` | `svelte` | `intent-element`). `@hyperfixi/mcp-server` loses
|
|
62
|
+
`compile_hyperscript`, `execute_lse`, `lse_to_hyperscript`'s `compile` option and
|
|
63
|
+
`generate_tests`' `executionMode`, leaving 106 tools. The loop is now `validate_and_compile`
|
|
64
|
+
(name kept), then repair, then the hyperscript as is in `_="…"`.
|
|
65
|
+
- **`@hyperfixi/vite-plugin`'s compile mode** (#1360). `mode: 'compile'` warns and builds the
|
|
66
|
+
engine bundle. The exports `CompiledHandler`, `CompileOptions` and
|
|
67
|
+
`set/clear/hasSemanticParser` are removed.
|
|
68
|
+
- **Smaller removals.** `@hyperfixi/core/reference` loses `availability`, `BundleAvailability`
|
|
69
|
+
and `getCommandsByAvailability` (#1363). `@hyperfixi/speech` loses `speechPlugin`,
|
|
70
|
+
`speakCommand`, `askCommand` and `answerCommand`; the engine has `ask` / `answer` (#1358).
|
|
71
|
+
`@hyperfixi/intent-element` loses its `evalLSENode` fallback (#1356).
|
|
72
|
+
`@hyperfixi/patterns-reference` loses four rows that held only retired htmx attributes, and
|
|
73
|
+
`hx-live-with-mutator` is renamed `live-with-handler` (#1348). Of the never-published VS Code
|
|
74
|
+
extensions, the LokaScript one loses its debugger and the standalone `_hyperscript` one is
|
|
75
|
+
retired (#1361).
|
|
76
|
+
|
|
77
|
+
### Deprecated
|
|
78
|
+
|
|
79
|
+
- **`@hyperfixi/reactivity`, `@hyperfixi/realtime`, `@hyperfixi/components`**: deprecated on npm,
|
|
80
|
+
last version 3.3.0 (#1358). Use the engine's built-in `live` / `when` / `bind`, htmx 4's
|
|
81
|
+
`hx-sse` / `hx-ws`, and upstream's component extension.
|
|
82
|
+
- **`@hyperfixi/types-browser`'s `LokaScriptCoreAPI`**: a deprecated alias of `HyperfixiAPI`
|
|
83
|
+
(#1356).
|
|
84
|
+
|
|
85
|
+
### Changed
|
|
86
|
+
|
|
87
|
+
- ⚠ **`@hyperfixi/core` is the engine plus tooling** (#1368). The root is
|
|
88
|
+
`export * from '@hyperfixi/engine'` and `VERSION`: `register`, `everything` and each grammar
|
|
89
|
+
module, `api`, `parse`, `evaluate`, `processNode`, `boot`, and the AST types. The engine stays
|
|
90
|
+
external, so both packages share one grammar. Kept: `/multilingual`, `/ast-utils`,
|
|
91
|
+
`/reference`, `/metadata`, `/lsp-metadata`, `/browser`.
|
|
92
|
+
- ⚠ **`hyperfixi.js` (`@hyperfixi/core/browser`) is the engine's `hyperfixi-hs.js`**, byte for
|
|
93
|
+
byte: 34 KB gzipped instead of ~352 KB (#1355). `window.hyperfixi` is `window._hyperscript`,
|
|
94
|
+
upstream-shaped (`evaluate`, `parse`, `process`, `use`, `config`, `addSourceTransform`). Parse
|
|
95
|
+
errors are a `hyperscript:parse-error` event on the element plus a `console.error` (#1354).
|
|
96
|
+
- ⚠ **Runtime semantics follow upstream** wherever core's differed. `swap #a with #b` exchanges
|
|
97
|
+
the elements; `show` / `hide … with *opacity` honour the strategy; `tell` binds `you`, not `me`;
|
|
98
|
+
`set` on a selector sets every match; and `no ""` is true. MIGRATION.md has the full list.
|
|
99
|
+
- ⚠ **`@hyperfixi/vite-plugin` emits a bundle on `@hyperfixi/engine`** (#1343). There is one
|
|
100
|
+
tier: the grammar modules the scan finds. It weighs 17.9 KB gzipped for three commands (3.x lite:
|
|
101
|
+
3.9 KB) and 34.4 KB for everything; 3.x fell back to 352 KB on `fetch`. htmx is not bundled.
|
|
102
|
+
Non-English scripts are translated as the engine reads them. `devFallback: 'everything'` is new,
|
|
103
|
+
and `'full'` / `'hybrid-complete'` mean the same. The plugin no longer depends on core.
|
|
104
|
+
- ⚠ **`@hyperfixi/behaviors` runs on the engine** (peer `@hyperfixi/engine`; upstream works too).
|
|
105
|
+
Each behavior is defined with `host.evaluate(source)` and written in upstream's idioms.
|
|
106
|
+
Toggleable's `target` parameter is now `targetEl`. `LokaScriptInstance` / `LokaScriptWindow`
|
|
107
|
+
are now `HyperscriptHost` / `HyperscriptWindow` (#1338).
|
|
108
|
+
- ⚠ **`@hyperfixi/speech` is an engine module** (#1358). Install it with
|
|
109
|
+
`register(...everything, speak)`. It is ESM-only and peers on the engine. `speak` takes
|
|
110
|
+
upstream's syntax (`speak <text> [with voice|rate|pitch|volume <x>]…`) and waits for the
|
|
111
|
+
utterance to end.
|
|
112
|
+
- ⚠ **The localized htmx vocabulary moved** from `@hyperfixi/core/vocab/htmx/{lang}.js` to
|
|
113
|
+
`@lokascript/htmx-adapter/vocab/{lang}.js`; the data is unchanged (#1349).
|
|
114
|
+
- **`@hyperfixi/intent-element`** renders an intent to English with the page's semantic bundle
|
|
115
|
+
and runs it through the host's `evaluate` (`NO_RENDERER` without one). It peers on
|
|
116
|
+
`@hyperfixi/engine` and `@lokascript/semantic` (#1339, #1356).
|
|
117
|
+
- **`@lokascript/semantic` writes upstream's spelling in English** for core-only forms (#1346).
|
|
118
|
+
For example, `has` becomes `matches`, `prepend` becomes `put … at start of`, and swap strategies
|
|
119
|
+
become `put … into` / `before` / `after`. This reaches `translate(…, 'en')`,
|
|
120
|
+
`render(node, 'en')`, both adapters and MCP `translate_to_english`. In `fromSemanticAST`, a
|
|
121
|
+
handler's `then` chain is now its body (#1359).
|
|
122
|
+
- **The language tools read the engine's parse** (#1356, #1359, #1365).
|
|
123
|
+
`@lokascript/language-server` and MCP `validate_hyperscript` report the engine's errors
|
|
124
|
+
(`source: 'engine'`). Hover and symbols come from `@lokascript/semantic`, and some long handlers
|
|
125
|
+
show fewer commands than in 3.x. Hyperscript mode flags exactly `new X()` and `toggle <element>`.
|
|
126
|
+
`@lokascript/compilation-service` rejects natural-language input the engine cannot read
|
|
127
|
+
(`ENGINE_PARSE_ERROR`), and its generated Playwright tests load `hyperfixi-hs.js`. The language
|
|
128
|
+
server, the MCP server and the compilation service now peer on `@hyperfixi/engine`.
|
|
129
|
+
- **MCP**: `get_bundle_config` recommends `hyperfixi-hs.js`, plus an `adapter` field for
|
|
130
|
+
non-English. `analyze_complexity` / `analyze_metrics` no longer count every comparison as a
|
|
131
|
+
decision. The `debug_*` tools point to `log` and `breakpoint`. `UNSUPPORTED_QUERY_LITERAL` is
|
|
132
|
+
gone (#1350, #1352, #1359, #1361, #1364).
|
|
133
|
+
- **`@hyperfixi/core/reference`, `/lsp-metadata`, `/metadata` describe the engine** (#1355,
|
|
134
|
+
#1363). They cover its 53 commands, adding `for`, `ask`, `answer` and `beep!`. Examples are in
|
|
135
|
+
upstream spelling and each is checked to parse; descriptions of core-only semantics (`pick`,
|
|
136
|
+
`beep`, `swap`) are fixed. `FEATURE_KEYWORDS` gains `install`, `when`, `live` and `bind`, and
|
|
137
|
+
`bundleInfo` holds one row.
|
|
138
|
+
- **Dependencies.** `@lokascript/i18n`, `@hyperfixi/testing-framework`, `@hyperfixi/vite-plugin`,
|
|
139
|
+
`@hyperfixi/behaviors`, `@hyperfixi/speech` and `@hyperfixi/intent-element` no longer depend
|
|
140
|
+
on core. Core drops `@lokascript/intent`, morphlex, tslib and its optional peers. Versions are
|
|
141
|
+
lockstep, so upgrade `@hyperfixi/*` and `@lokascript/*` together. `@hyperfixi/mcp-server`,
|
|
142
|
+
`@lokascript/framework` (tests) and `@hyperfixi/server-bridge` (tests) range on
|
|
143
|
+
`@lokascript/domains ^3.0.1`, the first domains release whose peers accept framework,
|
|
144
|
+
semantic and intent 4.x (`^3.1.0 || ^4.0.0`).
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- **`@hyperfixi/engine` exports `expr`**, so a grammar module can live in another package
|
|
149
|
+
(#1358).
|
|
150
|
+
- **`@hyperfixi/core/ast-utils`'s `withEnginePositions`** gives interchange nodes the source
|
|
151
|
+
spans of the engine's parse (#1359).
|
|
152
|
+
|
|
153
|
+
### Fixed
|
|
154
|
+
|
|
155
|
+
- **`@hyperfixi/engine`** accepts upstream's `beep!` command (`beep! a, b`); 3.3.0 rejected it
|
|
156
|
+
(#1362).
|
|
157
|
+
- **`@hyperfixi/types-browser`** types `window.hyperfixi` / `window._hyperscript` as the engine's
|
|
158
|
+
`HyperfixiAPI`. 3.3.0 re-exported a `./globals` it never emitted, so `window.hyperfixi` was
|
|
159
|
+
untyped (#1356).
|
|
160
|
+
- **Semantic browser bundles** (#1351). Single-language and regional bundles (es, ja,
|
|
161
|
+
east-asian, …) registered no English, so the hyperscript adapter left scripts untranslated. They
|
|
162
|
+
now register it (+~2.2 KB gzipped) and export `translate`. The lite adapter finds any
|
|
163
|
+
`LokaScriptSemantic*` global.
|
|
164
|
+
- **`@lokascript/semantic`** (#1338, #1343, #1347). `/core` plus a language module no longer
|
|
165
|
+
throws "No patterns registered". `on click from (x or me)` parses in th and zh. A `js … end`
|
|
166
|
+
block no longer ends its handler in ja / ko / hi / tr / qu / bn. An options object's `}` is no
|
|
167
|
+
longer read as an SOV event name.
|
|
168
|
+
- **Language server and MCP** (#1359, #1363, #1365). `beep!` has hover docs. `set X to`
|
|
169
|
+
completions offer values. Hyperscript-mode errors land on the form, not line 0. Hover no longer
|
|
170
|
+
shows a second `on click`.
|
|
171
|
+
|
|
10
172
|
## [3.3.0] - 2026-10-02
|
|
11
173
|
|
|
12
174
|
The first publication of `@hyperfixi/engine`, the hyperscript engine meant to replace the one
|
package/README.md
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
# @hyperfixi/behaviors
|
|
2
2
|
|
|
3
|
-
Reusable hyperscript behaviors
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Reusable hyperscript behaviors. A behavior is installed on any element with
|
|
4
|
+
`_="install BehaviorName(params)"` and is defined in **pure hyperscript** (its `source`),
|
|
5
|
+
in upstream `_hyperscript`'s own idioms. The host is `@hyperfixi/engine` (the
|
|
6
|
+
`hyperfixi-hs.js` script-tag bundle); every source also runs, unchanged, on upstream
|
|
7
|
+
`_hyperscript` 0.9.93.
|
|
6
8
|
|
|
7
9
|
```html
|
|
8
|
-
<script src="hyperfixi.js"></script>
|
|
10
|
+
<script src="hyperfixi-hs.js"></script>
|
|
9
11
|
<script src="resolver.browser.global.js"></script>
|
|
10
|
-
<!-- install X just works —
|
|
12
|
+
<!-- install X just works — the bundle defines every behavior on the host -->
|
|
11
13
|
<button _="install Toggleable(cls: 'active')">Toggle</button>
|
|
12
14
|
```
|
|
13
15
|
|
|
16
|
+
## Hosts
|
|
17
|
+
|
|
18
|
+
The bundle (and the npm `register*()` functions) define each behavior with the host's
|
|
19
|
+
`evaluate(source)`, exactly as a page's `<script type="text/hyperscript">` would. Anything
|
|
20
|
+
shaped like upstream's `_hyperscript` object is a host; `window.hyperfixi` is tried first,
|
|
21
|
+
then `window._hyperscript`.
|
|
22
|
+
|
|
23
|
+
- **`@hyperfixi/engine`** (`hyperfixi-hs.js`): the peer dependency, and what the tests run
|
|
24
|
+
on. `install Toggleable` with no arguments works.
|
|
25
|
+
- **upstream `_hyperscript`** (0.9.93): every source runs the same, measured in a browser
|
|
26
|
+
(2026-10-03). One difference, upstream's: `install Toggleable` _without parentheses_ throws
|
|
27
|
+
there, so write `install Toggleable()` (or give an argument) on upstream.
|
|
28
|
+
|
|
29
|
+
Two things the sources never do, because no hyperscript engine reads them that way: default a
|
|
30
|
+
parameter with a bare `set cls to "active"` (it makes a local the handlers never see — the
|
|
31
|
+
sources write `set element's cls to …`), and name a parameter `target` (that is hyperscript's
|
|
32
|
+
own name for the event target, so Toggleable's is `targetEl`).
|
|
33
|
+
|
|
14
34
|
## The boundary rule — what a behavior _is_
|
|
15
35
|
|
|
16
36
|
> **A behavior is a named, parameterized, _reusable inline script_ — `on event →
|
|
@@ -22,10 +42,10 @@ This rule is why the set is small and tiered. Most "behaviors" people reach for
|
|
|
22
42
|
really just short inline scripts — see [Recipes](#recipes--most-things-are-inline-scripts).
|
|
23
43
|
|
|
24
44
|
A single source of truth drives every consumer: the hyperscript `source` string in
|
|
25
|
-
each `src/schemas/*.schema.ts`. The npm `register*()` functions, the
|
|
26
|
-
`resolver.browser.global.js` bundle, and `@hyperfixi/patterns-reference` all
|
|
45
|
+
each `src/schemas/*.schema.ts`. The npm `register*()` functions, the browser
|
|
46
|
+
`resolver.browser.global.js` bundle, and `@hyperfixi/patterns-reference` all define
|
|
27
47
|
that **same source** — one runtime path, identical in the browser and Node. **Every
|
|
28
|
-
behavior
|
|
48
|
+
behavior is defined from `source`; there is no imperative-JS installer.** (An earlier
|
|
29
49
|
imperative-installer experiment forked a second, diverging path; it has been removed
|
|
30
50
|
for all tiers — including the three experimental components, which now run their
|
|
31
51
|
pointer loops from `source` like everything else.)
|
|
@@ -87,7 +107,7 @@ recipe to an installed behavior only when it is genuinely reusable and parameter
|
|
|
87
107
|
|
|
88
108
|
```javascript
|
|
89
109
|
import { registerAll } from '@hyperfixi/behaviors';
|
|
90
|
-
await registerAll(); //
|
|
110
|
+
await registerAll(); // defines every behavior on window.hyperfixi (or window._hyperscript)
|
|
91
111
|
|
|
92
112
|
import { registerToggleable } from '@hyperfixi/behaviors/toggleable';
|
|
93
113
|
await registerToggleable(); // tree-shakeable single behavior
|
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
"use strict";var HyperFixiBehaviors=(()=>{var
|
|
1
|
+
"use strict";var HyperFixiBehaviors=(()=>{var K=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var Mt=Object.getOwnPropertyNames;var Dt=Object.prototype.hasOwnProperty;var i=(e,t)=>()=>(e&&(t=e(e=0)),t);var d=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},It=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let p of Mt(t))!Dt.call(e,p)&&p!==r&&K(e,p,{get:()=>t[p],enumerable:!(s=Ot(t,p))||s.enumerable});return e};var Lt=e=>It(K({},"__esModule",{value:!0}),e);var u,J=i(()=>{"use strict";u={name:"Draggable",category:"ui",tier:"core",version:"1.0.0",description:"Makes elements draggable with pointer events (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragHandle",type:"selector",optional:!0,default:"me",description:"CSS selector for the drag handle element"}],events:[{name:"draggable:start",description:"Fired when drag begins"},{name:"draggable:move",description:"Fired during each movement"},{name:"draggable:end",description:"Fired when drag completes"}],requirements:["position: absolute or position: fixed on the element"],source:`
|
|
2
2
|
behavior Draggable(dragHandle)
|
|
3
|
-
|
|
4
|
-
if no dragHandle set dragHandle to me
|
|
5
|
-
end
|
|
6
|
-
on pointerdown(clientX, clientY) from dragHandle
|
|
3
|
+
on pointerdown(clientX, clientY) from (dragHandle or me)
|
|
7
4
|
halt the event
|
|
8
5
|
trigger draggable:start
|
|
9
|
-
|
|
10
|
-
set
|
|
11
|
-
measure y
|
|
12
|
-
set startY to it
|
|
13
|
-
set xoff to clientX - startX
|
|
14
|
-
set yoff to clientY - startY
|
|
6
|
+
set xoff to clientX - my offsetLeft
|
|
7
|
+
set yoff to clientY - my offsetTop
|
|
15
8
|
repeat until event pointerup from document
|
|
16
9
|
wait for pointermove(clientX, clientY) or
|
|
17
10
|
pointerup(clientX, clientY) from document
|
|
@@ -20,15 +13,9 @@ behavior Draggable(dragHandle)
|
|
|
20
13
|
end
|
|
21
14
|
trigger draggable:end
|
|
22
15
|
end
|
|
23
|
-
end
|
|
24
|
-
`.trim()}});function a(){if(typeof window>"u")return null;let t=window;return t.lokascript||t.hyperfixi||null}var c=i(()=>{"use strict"});var Ke={};l(Ke,{default:()=>ee,draggableMetadata:()=>Z,draggableSource:()=>Q,registerDraggable:()=>E});async function E(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(u.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Draggable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var Q,Z,ee,_=i(()=>{"use strict";K();c();Q=u.source,Z=u;a()&&E().catch(console.error);ee={source:u.source,metadata:u,register:E}});var p,te=i(()=>{"use strict";p={name:"Removable",category:"data",tier:"common",version:"1.2.0",description:"Makes elements removable on click",parameters:[{name:"triggerEl",type:"selector",optional:!0,default:"me",description:"Element that triggers removal (e.g., a close button)"},{name:"confirmRemoval",type:"boolean",optional:!0,default:!1,description:"Show confirmation dialog before removal"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect: "fade" or "none"'}],events:[{name:"removable:before",description:"Fired before removal (cancelable)"},{name:"removable:removed",description:"Fired after removal"}],source:`
|
|
16
|
+
end`.trim()}});function o(){if(typeof window>"u")return null;let e=window,t=e.hyperfixi??e._hyperscript;return t&&typeof t.evaluate=="function"?t:null}function a(e,t){let r=t??o();if(!r)throw new Error(`No hyperscript host found: load @hyperfixi/engine (hyperfixi-hs.js) before defining ${e.name}.`);try{r.evaluate(e.source)}catch(s){throw new Error(`Failed to define ${e.name} behavior: ${s.message}`)}}var l=i(()=>{"use strict"});var Je={};d(Je,{default:()=>ee,draggableMetadata:()=>Z,draggableSource:()=>Q,registerDraggable:()=>A});async function A(e){a(u,e)}var Q,Z,ee,z=i(()=>{"use strict";J();l();Q=u.source,Z=u;o()&&A().catch(console.error);ee={source:u.source,metadata:u,register:A}});var f,te=i(()=>{"use strict";f={name:"Removable",category:"data",tier:"common",version:"1.2.0",description:"Makes elements removable on click",parameters:[{name:"triggerEl",type:"selector",optional:!0,default:"me",description:"Element that triggers removal (e.g., a close button)"},{name:"confirmRemoval",type:"boolean",optional:!0,default:!1,description:"Show confirmation dialog before removal"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect: "fade" or "none"'}],events:[{name:"removable:before",description:"Fired before removal (cancelable)"},{name:"removable:removed",description:"Fired after removal"}],source:`
|
|
25
17
|
behavior Removable(triggerEl, confirmRemoval, effect)
|
|
26
|
-
|
|
27
|
-
if triggerEl is undefined
|
|
28
|
-
set triggerEl to me
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
on click from triggerEl
|
|
18
|
+
on click from (triggerEl or me)
|
|
32
19
|
if confirmRemoval
|
|
33
20
|
js(me)
|
|
34
21
|
if (!window.confirm("Are you sure?")) return "cancel";
|
|
@@ -44,55 +31,44 @@ behavior Removable(triggerEl, confirmRemoval, effect)
|
|
|
44
31
|
trigger removable:removed
|
|
45
32
|
remove me
|
|
46
33
|
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
behavior Toggleable(cls, target)
|
|
34
|
+
end`.trim()}});var Qe={};d(Qe,{default:()=>ie,registerRemovable:()=>R,removableMetadata:()=>oe,removableSource:()=>re});async function R(e){a(f,e)}var re,oe,ie,W=i(()=>{"use strict";te();l();re=f.source,oe=f;o()&&R().catch(console.error);ie={source:f.source,metadata:f,register:R}});var v,ae=i(()=>{"use strict";v={name:"Toggleable",category:"form",tier:"core",version:"1.0.0",description:"Toggles a CSS class on click",parameters:[{name:"cls",type:"string",optional:!0,default:"active",description:"CSS class to toggle"},{name:"targetEl",type:"selector",optional:!0,default:"me",description:"Element to toggle the class on (not `target`: that is hyperscript's name for the event target)"}],events:[{name:"toggleable:on",description:"Fired when class is added"},{name:"toggleable:off",description:"Fired when class is removed"}],source:`
|
|
35
|
+
behavior Toggleable(cls, targetEl)
|
|
50
36
|
init
|
|
51
|
-
if cls is undefined
|
|
52
|
-
|
|
53
|
-
end
|
|
54
|
-
if target is undefined
|
|
55
|
-
set target to me
|
|
56
|
-
end
|
|
37
|
+
if cls is undefined set element's cls to "active" end
|
|
38
|
+
if targetEl is undefined set element's targetEl to me end
|
|
57
39
|
end
|
|
58
40
|
on click
|
|
59
|
-
toggle .{cls} on
|
|
60
|
-
js(
|
|
61
|
-
var eventName =
|
|
62
|
-
|
|
41
|
+
toggle .{cls} on targetEl
|
|
42
|
+
js(targetEl, cls)
|
|
43
|
+
var eventName = targetEl.classList.contains(cls) ? 'toggleable:on' : 'toggleable:off';
|
|
44
|
+
targetEl.dispatchEvent(new CustomEvent(eventName, { bubbles: true }));
|
|
63
45
|
end
|
|
64
46
|
end
|
|
65
|
-
end`.trim()}});var Ze={};
|
|
47
|
+
end`.trim()}});var Ze={};d(Ze,{default:()=>ce,registerToggleable:()=>H,toggleableMetadata:()=>ne,toggleableSource:()=>se});async function H(e){a(v,e)}var se,ne,ce,N=i(()=>{"use strict";ae();l();se=v.source,ne=v;o()&&H().catch(console.error);ce={source:v.source,metadata:v,register:H}});var h,le=i(()=>{"use strict";h={name:"Sortable",category:"ui",tier:"common",version:"1.0.0",description:"Makes child elements reorderable via drag-and-drop (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"dragClass",type:"string",optional:!0,default:"sorting",description:"CSS class added to item during drag"}],events:[{name:"sortable:start",description:"Fired when drag begins"},{name:"sortable:move",description:"Fired during drag \u2014 handle this event to reorder DOM elements"},{name:"sortable:end",description:"Fired when drag completes"}],requirements:["Users must handle DOM reordering in sortable:move event handlers"],source:`
|
|
66
48
|
behavior Sortable(dragClass)
|
|
67
|
-
init
|
|
68
|
-
if dragClass is undefined
|
|
69
|
-
set dragClass to "sorting"
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
49
|
on pointerdown(clientY) from me
|
|
73
50
|
set item to the target.closest("li")
|
|
74
51
|
if item is null
|
|
75
52
|
exit
|
|
76
53
|
end
|
|
77
54
|
halt the event
|
|
78
|
-
|
|
55
|
+
set cls to dragClass or "sorting"
|
|
56
|
+
add .{cls} to item
|
|
79
57
|
trigger sortable:start on me
|
|
80
58
|
repeat until event pointerup from document
|
|
81
59
|
wait for pointermove(clientY) or pointerup(clientY) from document
|
|
82
60
|
trigger sortable:move on me
|
|
83
61
|
end
|
|
84
|
-
remove .{
|
|
62
|
+
remove .{cls} from item
|
|
85
63
|
trigger sortable:end on me
|
|
86
64
|
end
|
|
87
|
-
end`.trim()}});var et={};
|
|
65
|
+
end`.trim()}});var et={};d(et,{default:()=>pe,registerSortable:()=>T,sortableMetadata:()=>me,sortableSource:()=>de});async function T(e){a(h,e)}var de,me,pe,_=i(()=>{"use strict";le();l();de=h.source,me=h;o()&&T().catch(console.error);pe={source:h.source,metadata:h,register:T}});var b,ue=i(()=>{"use strict";b={name:"Resizable",category:"ui",tier:"optional",version:"1.0.0",description:"Makes elements resizable by dragging (EXPERIMENTAL \u2014 stateful async component, beyond the inline-scripting boundary; not part of the curated set)",parameters:[{name:"minWidth",type:"number",optional:!0,default:50,description:"Minimum width in pixels"},{name:"minHeight",type:"number",optional:!0,default:50,description:"Minimum height in pixels"},{name:"maxWidth",type:"number",optional:!0,default:9999,description:"Maximum width in pixels"},{name:"maxHeight",type:"number",optional:!0,default:9999,description:"Maximum height in pixels"}],events:[{name:"resizable:start",description:"Fired when resize begins"},{name:"resizable:resize",description:"Fired during resize"},{name:"resizable:end",description:"Fired when resize completes"}],source:`
|
|
88
66
|
behavior Resizable(minWidth, minHeight, maxWidth, maxHeight)
|
|
89
67
|
on pointerdown(clientX, clientY) from me
|
|
90
68
|
halt the event
|
|
91
69
|
trigger resizable:start
|
|
92
|
-
|
|
93
|
-
set
|
|
94
|
-
measure height
|
|
95
|
-
set startHeight to it
|
|
70
|
+
set startWidth to my offsetWidth
|
|
71
|
+
set startHeight to my offsetHeight
|
|
96
72
|
set startX to clientX
|
|
97
73
|
set startY to clientY
|
|
98
74
|
repeat until event pointerup from document
|
|
@@ -109,16 +85,11 @@ behavior Resizable(minWidth, minHeight, maxWidth, maxHeight)
|
|
|
109
85
|
end
|
|
110
86
|
trigger resizable:end
|
|
111
87
|
end
|
|
112
|
-
end
|
|
113
|
-
`.trim()}});var tt={};l(tt,{default:()=>ve,registerResizable:()=>R,resizableMetadata:()=>he,resizableSource:()=>fe});async function R(t){let e=t||a();if(!e)throw new Error("LokaScript not found. Make sure @hyperfixi/core is loaded before registering behaviors.");let r=e.compileSync(v.source,{traditional:!0});if(!r.ok)throw new Error(`Failed to compile Resizable behavior: ${JSON.stringify(r.errors)}`);let o=e.createContext?e.createContext():{locals:new Map,globals:new Map};await e.execute(r.ast,o)}var fe,he,ve,W=i(()=>{"use strict";pe();c();fe=v.source,he=v;a()&&R().catch(console.error);ve={source:v.source,metadata:v,register:R}});var b,be=i(()=>{"use strict";b={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:`
|
|
88
|
+
end`.trim()}});var tt={};d(tt,{default:()=>he,registerResizable:()=>C,resizableMetadata:()=>ve,resizableSource:()=>fe});async function C(e){a(b,e)}var fe,ve,he,j=i(()=>{"use strict";ue();l();fe=b.source,ve=b;o()&&C().catch(console.error);he={source:b.source,metadata:b,register:C}});var g,be=i(()=>{"use strict";g={name:"Clipboard",category:"ui",tier:"core",version:"1.0.0",description:"Copies text to clipboard on click with visual feedback",parameters:[{name:"text",type:"string",optional:!0,description:"Literal text to copy (takes priority over source)"},{name:"source",type:"selector",optional:!0,default:"me",description:"Element whose textContent or value is copied"},{name:"feedback",type:"selector",optional:!0,description:"Element to show .copied feedback on (defaults to the installed element)"},{name:"feedbackDuration",type:"number",optional:!0,default:2e3,description:"Duration in ms to show .copied class feedback"}],events:[{name:"clipboard:copied",description:"Fired after text is copied successfully"},{name:"clipboard:error",description:"Fired when clipboard write fails"}],requirements:["navigator.clipboard.writeText() requires HTTPS or localhost",'Falls back to document.execCommand("copy") for older browsers'],source:`
|
|
114
89
|
behavior Clipboard(text, source, feedback, feedbackDuration)
|
|
115
90
|
init
|
|
116
|
-
if feedbackDuration is undefined
|
|
117
|
-
|
|
118
|
-
end
|
|
119
|
-
if source is undefined
|
|
120
|
-
set source to me
|
|
121
|
-
end
|
|
91
|
+
if feedbackDuration is undefined set element's feedbackDuration to 2000 end
|
|
92
|
+
if source is undefined set element's source to me end
|
|
122
93
|
end
|
|
123
94
|
on click
|
|
124
95
|
if text is not undefined
|
|
@@ -155,18 +126,12 @@ behavior Clipboard(text, source, feedback, feedbackDuration)
|
|
|
155
126
|
})();
|
|
156
127
|
end
|
|
157
128
|
end
|
|
158
|
-
end`.trim()}});var rt={};
|
|
129
|
+
end`.trim()}});var rt={};d(rt,{clipboardMetadata:()=>ye,clipboardSource:()=>ge,default:()=>xe,registerClipboard:()=>k});async function k(e){a(g,e)}var ge,ye,xe,Y=i(()=>{"use strict";be();l();ge=g.source,ye=g;o()&&k().catch(console.error);xe={source:g.source,metadata:g,register:k}});var y,Se=i(()=>{"use strict";y={name:"AutoDismiss",category:"ui",tier:"core",version:"1.0.0",description:"Auto-removes elements after a delay with optional pause-on-hover",parameters:[{name:"delay",type:"number",optional:!0,default:5e3,description:"Time in ms before the element is removed"},{name:"pauseOnHover",type:"boolean",optional:!0,default:!0,description:"Pause the countdown when the mouse hovers over the element"},{name:"effect",type:"string",optional:!0,default:"none",enum:["fade","none"],description:'Transition effect before removal: "fade" or "none"'}],events:[{name:"autodismiss:start",description:"Fired when the countdown timer starts"},{name:"autodismiss:dismissed",description:"Fired before removal (cancelable via preventDefault)"},{name:"autodismiss:paused",description:"Fired when the timer is paused on hover"},{name:"autodismiss:resumed",description:"Fired when the timer resumes on mouseleave"}],source:`
|
|
159
130
|
behavior AutoDismiss(delay, pauseOnHover, effect)
|
|
160
131
|
init
|
|
161
|
-
if delay is undefined
|
|
162
|
-
|
|
163
|
-
end
|
|
164
|
-
if pauseOnHover is undefined
|
|
165
|
-
set pauseOnHover to true
|
|
166
|
-
end
|
|
167
|
-
if effect is undefined
|
|
168
|
-
set effect to "none"
|
|
169
|
-
end
|
|
132
|
+
if delay is undefined set element's delay to 5000 end
|
|
133
|
+
if pauseOnHover is undefined set element's pauseOnHover to true end
|
|
134
|
+
if effect is undefined set element's effect to "none" end
|
|
170
135
|
js(me, delay, effect, pauseOnHover)
|
|
171
136
|
me.dispatchEvent(new CustomEvent('autodismiss:start', { bubbles: true }));
|
|
172
137
|
var remaining = delay;
|
|
@@ -208,12 +173,10 @@ behavior AutoDismiss(delay, pauseOnHover, effect)
|
|
|
208
173
|
}
|
|
209
174
|
end
|
|
210
175
|
end
|
|
211
|
-
end`.trim()}});var ot={};
|
|
176
|
+
end`.trim()}});var ot={};d(ot,{autoDismissMetadata:()=>Be,autoDismissSource:()=>we,default:()=>Ee,registerAutoDismiss:()=>F});async function F(e){a(y,e)}var we,Be,Ee,X=i(()=>{"use strict";Se();l();we=y.source,Be=y;o()&&F().catch(console.error);Ee={source:y.source,metadata:y,register:F}});var x,Ae=i(()=>{"use strict";x={name:"ClickOutside",category:"ui",tier:"core",version:"1.0.0",description:"Fires an event when the user clicks outside the element",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the listener is active (can be toggled programmatically)"}],events:[{name:"clickoutside",description:"Fired when a pointer press occurs outside the element"},{name:"clickoutside:activate",description:"Listen for this event to programmatically activate detection"},{name:"clickoutside:deactivate",description:"Listen for this event to programmatically deactivate detection"}],requirements:["Uses pointerdown instead of click to avoid timing issues with removed elements"],source:`
|
|
212
177
|
behavior ClickOutside(active)
|
|
213
178
|
init
|
|
214
|
-
if active is undefined
|
|
215
|
-
set active to true
|
|
216
|
-
end
|
|
179
|
+
if active is undefined set element's active to true end
|
|
217
180
|
end
|
|
218
181
|
on pointerdown from document
|
|
219
182
|
js(me, active, event)
|
|
@@ -224,20 +187,16 @@ behavior ClickOutside(active)
|
|
|
224
187
|
end
|
|
225
188
|
end
|
|
226
189
|
on clickoutside:activate
|
|
227
|
-
set active to true
|
|
190
|
+
set element's active to true
|
|
228
191
|
end
|
|
229
192
|
on clickoutside:deactivate
|
|
230
|
-
set active to false
|
|
193
|
+
set element's active to false
|
|
231
194
|
end
|
|
232
|
-
end`.trim()}});var
|
|
195
|
+
end`.trim()}});var it={};d(it,{clickOutsideMetadata:()=>He,clickOutsideSource:()=>Re,default:()=>Te,registerClickOutside:()=>O});async function O(e){a(x,e)}var Re,He,Te,$=i(()=>{"use strict";Ae();l();Re=x.source,He=x;o()&&O().catch(console.error);Te={source:x.source,metadata:x,register:O}});var S,Ce=i(()=>{"use strict";S={name:"FocusTrap",category:"ui",tier:"core",version:"1.0.0",description:"Confines Tab navigation inside an element with ARIA support",parameters:[{name:"active",type:"boolean",optional:!0,default:!0,description:"Whether the trap is active on install"},{name:"initialFocus",type:"selector",optional:!0,description:"Element to focus when the trap activates"},{name:"returnFocus",type:"boolean",optional:!0,default:!0,description:"Restore focus to the previously focused element on deactivation"}],events:[{name:"focustrap:activated",description:"Fired when the trap is activated"},{name:"focustrap:deactivated",description:"Fired when the trap is deactivated"}],requirements:['Sets aria-modal="true" on the element when active',"Listens for focustrap:activate and focustrap:deactivate custom events for programmatic control"],source:`
|
|
233
196
|
behavior FocusTrap(active, initialFocus, returnFocus)
|
|
234
197
|
init
|
|
235
|
-
if active is undefined
|
|
236
|
-
|
|
237
|
-
end
|
|
238
|
-
if returnFocus is undefined
|
|
239
|
-
set returnFocus to true
|
|
240
|
-
end
|
|
198
|
+
if active is undefined set element's active to true end
|
|
199
|
+
if returnFocus is undefined set element's returnFocus to true end
|
|
241
200
|
js(me, active, initialFocus, returnFocus)
|
|
242
201
|
var FOCUSABLE = 'a[href],button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex]:not([tabindex="-1"])';
|
|
243
202
|
var isActive = false;
|
|
@@ -277,18 +236,12 @@ behavior FocusTrap(active, initialFocus, returnFocus)
|
|
|
277
236
|
if (active) activate();
|
|
278
237
|
end
|
|
279
238
|
end
|
|
280
|
-
end`.trim()}});var
|
|
239
|
+
end`.trim()}});var at={};d(at,{default:()=>Oe,focusTrapMetadata:()=>Fe,focusTrapSource:()=>ke,registerFocusTrap:()=>M});async function M(e){a(S,e)}var ke,Fe,Oe,U=i(()=>{"use strict";Ce();l();ke=S.source,Fe=S;o()&&M().catch(console.error);Oe={source:S.source,metadata:S,register:M}});var w,Me=i(()=>{"use strict";w={name:"ScrollReveal",category:"layout",tier:"common",version:"1.0.0",description:"Adds a class when the element enters the viewport via IntersectionObserver",parameters:[{name:"cls",type:"string",optional:!0,default:"revealed",description:"CSS class added when element enters viewport"},{name:"threshold",type:"number",optional:!0,default:.1,description:"Intersection ratio threshold (0-1) for triggering"},{name:"once",type:"boolean",optional:!0,default:!0,description:"If true, disconnect observer after first intersection"}],events:[{name:"scrollreveal:enter",description:"Fired when the element enters the viewport"},{name:"scrollreveal:exit",description:"Fired when the element exits the viewport"}],requirements:["Uses IntersectionObserver API (supported in all modern browsers)"],source:`
|
|
281
240
|
behavior ScrollReveal(cls, threshold, once)
|
|
282
241
|
init
|
|
283
|
-
if cls is undefined
|
|
284
|
-
|
|
285
|
-
end
|
|
286
|
-
if threshold is undefined
|
|
287
|
-
set threshold to 0.1
|
|
288
|
-
end
|
|
289
|
-
if once is undefined
|
|
290
|
-
set once to true
|
|
291
|
-
end
|
|
242
|
+
if cls is undefined set element's cls to "revealed" end
|
|
243
|
+
if threshold is undefined set element's threshold to 0.1 end
|
|
244
|
+
if once is undefined set element's once to true end
|
|
292
245
|
js(me, cls, threshold, once)
|
|
293
246
|
var obs = new IntersectionObserver(function(entries) {
|
|
294
247
|
for (var i = 0; i < entries.length; i++) {
|
|
@@ -305,21 +258,13 @@ behavior ScrollReveal(cls, threshold, once)
|
|
|
305
258
|
obs.observe(me);
|
|
306
259
|
end
|
|
307
260
|
end
|
|
308
|
-
end`.trim()}});var st={};
|
|
261
|
+
end`.trim()}});var st={};d(st,{default:()=>Le,registerScrollReveal:()=>D,scrollRevealMetadata:()=>Ie,scrollRevealSource:()=>De});async function D(e){a(w,e)}var De,Ie,Le,V=i(()=>{"use strict";Me();l();De=w.source,Ie=w;o()&&D().catch(console.error);Le={source:w.source,metadata:w,register:D}});var B,Pe=i(()=>{"use strict";B={name:"Tabs",category:"ui",tier:"core",version:"1.0.0",description:"WAI-ARIA compliant tabs with roving tabindex keyboard navigation. Auto-wires role, aria-selected, aria-controls, and aria-labelledby attributes.",parameters:[{name:"orientation",type:"string",optional:!0,default:"horizontal",enum:["horizontal","vertical"],description:"Arrow key direction: horizontal (Left/Right) or vertical (Up/Down)"},{name:"activeTab",type:"number",optional:!0,default:0,description:"Initial active tab index (zero-based)"},{name:"wrap",type:"boolean",optional:!0,default:!0,description:"Wrap to first/last tab when navigating past the end"},{name:"activeClass",type:"string",optional:!0,default:"active",description:"CSS class applied to the active tab and its panel"}],events:[{name:"tabs:change",description:"Fired before tab selection changes (cancelable via preventDefault)"},{name:"tabs:changed",description:"Fired after tab selection has changed"}],requirements:['Sets role="tablist" on the tab container','Sets role="tab" on tab buttons and role="tabpanel" on content panels',"Manages aria-selected, aria-controls, aria-labelledby, and tabindex","Keyboard: Arrow keys navigate, Home/End jump to first/last, Tab exits tablist"],source:`
|
|
309
262
|
behavior Tabs(orientation, activeTab, wrap, activeClass)
|
|
310
263
|
init
|
|
311
|
-
if orientation is undefined
|
|
312
|
-
|
|
313
|
-
end
|
|
314
|
-
if
|
|
315
|
-
set activeTab to 0
|
|
316
|
-
end
|
|
317
|
-
if wrap is undefined
|
|
318
|
-
set wrap to true
|
|
319
|
-
end
|
|
320
|
-
if activeClass is undefined
|
|
321
|
-
set activeClass to "active"
|
|
322
|
-
end
|
|
264
|
+
if orientation is undefined set element's orientation to "horizontal" end
|
|
265
|
+
if activeTab is undefined set element's activeTab to 0 end
|
|
266
|
+
if wrap is undefined set element's wrap to true end
|
|
267
|
+
if activeClass is undefined set element's activeClass to "active" end
|
|
323
268
|
js(me, orientation, activeTab, wrap, activeClass)
|
|
324
269
|
var tabs = Array.from(me.querySelectorAll('[role="tab"]'));
|
|
325
270
|
var panels = Array.from(me.querySelectorAll('[role="tabpanel"]'));
|
|
@@ -384,5 +329,5 @@ behavior Tabs(orientation, activeTab, wrap, activeClass)
|
|
|
384
329
|
});
|
|
385
330
|
end
|
|
386
331
|
end
|
|
387
|
-
end`.trim()}});var nt={};
|
|
332
|
+
end`.trim()}});var nt={};d(nt,{default:()=>Ne,registerTabs:()=>I,tabsMetadata:()=>We,tabsSource:()=>ze});async function I(e){a(B,e)}var ze,We,Ne,q=i(()=>{"use strict";Pe();l();ze=B.source,We=B;o()&&I().catch(console.error);Ne={source:B.source,metadata:B,register:I}});var Pt={};d(Pt,{ALL_BEHAVIOR_NAMES:()=>wt,AutoDismiss:()=>Ee,BEHAVIORS_BY_CATEGORY:()=>Bt,BEHAVIORS_BY_TIER:()=>Et,BEHAVIOR_CATEGORIES:()=>At,BEHAVIOR_TIERS:()=>Rt,CURATED_BEHAVIORS:()=>Ue,CURATION_STATUS:()=>G,ClickOutside:()=>Te,Clipboard:()=>xe,Draggable:()=>ee,EXPERIMENTAL_BEHAVIORS:()=>qe,FocusTrap:()=>Oe,OPTIONAL_BEHAVIORS:()=>Ve,Removable:()=>ie,Resizable:()=>he,ScrollReveal:()=>Le,Sortable:()=>pe,Tabs:()=>Ne,Toggleable:()=>ce,autoDismissMetadata:()=>Be,autoDismissSource:()=>we,clickOutsideMetadata:()=>He,clickOutsideSource:()=>Re,clipboardMetadata:()=>ye,clipboardSource:()=>ge,curationStatusOf:()=>Ht,draggableMetadata:()=>Z,draggableSource:()=>Q,focusTrapMetadata:()=>Fe,focusTrapSource:()=>ke,getAllSchemas:()=>vt,getAllSchemasRecord:()=>ht,getAvailableBehaviors:()=>Ye,getBehavior:()=>ct,getBehaviorsByCategory:()=>Xe,getBehaviorsByTier:()=>$e,getRegisteredBehaviors:()=>ft,getSchema:()=>dt,hasLoader:()=>ut,isCurated:()=>Tt,isRegistered:()=>pt,loadAll:()=>yt,loadBehavior:()=>L,preloadCategory:()=>gt,preloadTier:()=>bt,ready:()=>kt,registerAll:()=>Ct,registerAllWithRuntime:()=>St,registerAutoDismiss:()=>F,registerBehavior:()=>je,registerClickOutside:()=>O,registerClipboard:()=>k,registerDraggable:()=>A,registerFocusTrap:()=>M,registerLoader:()=>c,registerRemovable:()=>R,registerResizable:()=>C,registerSchema:()=>n,registerScrollReveal:()=>D,registerSortable:()=>T,registerTabs:()=>I,registerToggleable:()=>H,registerWithRuntime:()=>xt,removableMetadata:()=>oe,removableSource:()=>re,resizableMetadata:()=>ve,resizableSource:()=>fe,scrollRevealMetadata:()=>Ie,scrollRevealSource:()=>De,sortableMetadata:()=>me,sortableSource:()=>de,tabsMetadata:()=>We,tabsSource:()=>ze,toggleableMetadata:()=>ne,toggleableSource:()=>se,tryGetBehavior:()=>lt,tryGetSchema:()=>mt});z();W();N();_();j();Y();X();$();U();V();q();var m=new Map,E=new Map,P=new Map,_e=new Map;function je(e,t){m.set(e,t),t.metadata&&E.set(e,t.metadata)}function n(e){E.set(e.name,e)}function c(e,t){P.set(e,t)}function ct(e){let t=m.get(e);if(!t){let r=Array.from(m.keys()).join(", ");throw new Error(`Behavior '${e}' is not registered. Registered behaviors: ${r||"none"}. Use loadBehavior('${e}') to lazy load it.`)}return t}function lt(e){return m.get(e)}function dt(e){let t=E.get(e);if(!t)throw new Error(`Schema for behavior '${e}' is not registered. Use tryGetSchema('${e}') for a non-throwing alternative.`);return t}function mt(e){return E.get(e)}function pt(e){return m.has(e)}function ut(e){return P.has(e)}function ft(){return Array.from(m.keys())}function Ye(){let e=new Set([...m.keys(),...P.keys()]);return Array.from(e)}function Xe(e){let t=[];for(let[r,s]of E)s.category===e&&t.push(r);return t}function $e(e){let t=[];for(let[r,s]of E)s.tier===e&&t.push(r);return t}function vt(){return Array.from(E.values())}function ht(){let e={};for(let[t,r]of E)e[t]=r;return e}async function L(e){let t=m.get(e);if(t)return t;let r=_e.get(e);if(r)return r;let s=P.get(e);if(!s)throw new Error(`No loader registered for behavior '${e}'. Available loaders: ${Array.from(P.keys()).join(", ")||"none"}`);let p=s().then(Ft=>{let Ke=Ft.default;return je(e,Ke),_e.delete(e),Ke});return _e.set(e,p),p}async function bt(e){let t=$e(e);await Promise.all(t.map(r=>L(r).catch(s=>{console.warn(`[behaviors] Failed to preload '${r}' (tier: ${e}):`,s)})))}async function gt(e){let t=Xe(e);await Promise.all(t.map(r=>L(r).catch(s=>{console.warn(`[behaviors] Failed to preload '${r}' (category: ${e}):`,s)})))}async function yt(){let e=Ye();await Promise.all(e.map(t=>L(t).catch(r=>{console.warn(`[behaviors] Failed to load '${t}':`,r)})))}async function xt(e,t){await(await L(e)).register(t)}async function St(e){let t=Array.from(m.values()).map(r=>r.register(e));await Promise.all(t)}J();le();ue();te();ae();be();Se();Ae();Ce();Me();Pe();n(u);n(h);n(b);n(f);n(v);n(g);n(y);n(x);n(S);n(w);n(B);c("Draggable",()=>Promise.resolve().then(()=>(z(),Je)));c("Sortable",()=>Promise.resolve().then(()=>(_(),et)));c("Resizable",()=>Promise.resolve().then(()=>(j(),tt)));c("Removable",()=>Promise.resolve().then(()=>(W(),Qe)));c("Toggleable",()=>Promise.resolve().then(()=>(N(),Ze)));c("Clipboard",()=>Promise.resolve().then(()=>(Y(),rt)));c("AutoDismiss",()=>Promise.resolve().then(()=>(X(),ot)));c("ClickOutside",()=>Promise.resolve().then(()=>($(),it)));c("FocusTrap",()=>Promise.resolve().then(()=>(U(),at)));c("ScrollReveal",()=>Promise.resolve().then(()=>(V(),st)));c("Tabs",()=>Promise.resolve().then(()=>(q(),nt)));var wt=["Draggable","Sortable","Resizable","Removable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","ScrollReveal","Tabs"],Bt={ui:["Draggable","Sortable","Resizable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],data:["Removable"],animation:[],form:["Toggleable"],layout:["ScrollReveal"]},Et={core:["Draggable","Toggleable","Clipboard","AutoDismiss","ClickOutside","FocusTrap","Tabs"],common:["Sortable","Removable","ScrollReveal"],optional:["Resizable"]},At={Draggable:"ui",Sortable:"ui",Resizable:"ui",Removable:"data",Toggleable:"form",Clipboard:"ui",AutoDismiss:"ui",ClickOutside:"ui",FocusTrap:"ui",ScrollReveal:"layout",Tabs:"ui"},Rt={Draggable:"core",Sortable:"common",Resizable:"optional",Removable:"common",Toggleable:"core",Clipboard:"core",AutoDismiss:"core",ClickOutside:"core",FocusTrap:"core",ScrollReveal:"common",Tabs:"core"};var Ue=["Toggleable","Removable","ClickOutside","Clipboard","AutoDismiss"],Ve=["FocusTrap","ScrollReveal","Tabs"],qe=["Draggable","Sortable","Resizable"],G={...Object.fromEntries(Ue.map(e=>[e,"curated"])),...Object.fromEntries(Ve.map(e=>[e,"optional"])),...Object.fromEntries(qe.map(e=>[e,"experimental"]))};function Ht(e){return G[e]}function Tt(e){return G[e]==="curated"}z();W();N();_();j();Y();X();$();U();V();q();l();async function Ct(e){await Promise.all([A(e),R(e),H(e),T(e),C(e),k(e),F(e),O(e),M(e),D(e),I(e)])}var kt=null,Ge=o();Ge&&(kt=Ct(Ge).then(()=>{document.readyState!=="loading"&&Ge.processNode?.(document.body)}).catch(e=>{console.error("[behaviors] Auto-definition failed:",e)}));return Lt(Pt);})();
|
|
388
333
|
//# sourceMappingURL=all.browser.global.js.map
|