You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Require Elixir 1.19, vize 0.16.1, OXC 0.18, QuickBEAM 0.11.2, and Volt 0.19.4, dropping the older versions 0.3.4 also accepted. Volt is now a required dependency, used at compile time only. Building vize from source requires Rust 1.95.
The browser code is TypeScript in priv/ts, exported through the package's package.json: import patchLiveSocket from phoenix_vapor and getHybridHooks from phoenix_vapor/hybrid. priv/js/hybrid-bridge.js is gone, and patchLiveSocket was not in the Hex package before.
A hybrid module exports __mount(el, bridge, props), which returns applyProps/1 and unmount/0 for that instance, in place of the module-level __applyProps, __setBridge, and __unmount. Hybrid wrappers are phx-update="ignore", and their server HTML has no phx-* event attributes.
Full-runtime LiveViews take a :globals option mapping each package their bundle provides to its global, such as %{"reka-ui" => "RekaDialog"}. Only vue is mapped by default; reka-ui and @vueuse/* were hardcoded for the demo's bundle.
Reactive mount/3 assigns only the URL params the template reads.
An unknown :runtime option raises at compile time instead of falling back to detecting the mode.
Added
A page can mount the same hybrid component several times. Each mount has its own props and bridge.
defineProps is read in its object and TypeScript forms as well as as an array, using Vize's script analysis.
Guides for getting started and for each mode, and a cheatsheet.
Changed
Templates compiled into a module parse their expressions and compute fingerprints at compile time. Rendering a 500-row v-for went from 55 ms to 0.5 ms.
vize 0.16's vapor_split reports events and v-model as data, and PhoenixVapor renders them as phx-* attributes itself.
The full runtime reads its bundle once and caches it until the file changes, instead of reading it on every mount.
@vue/reactivity for Reactive mode is pinned in priv/ts/package.json and vendored by mix volt.priv.vendor, replacing a hand-copied build of 3.5.30.
Slot positions for direct DOM patching come from the browser's HTML parser instead of a hand-written one, which mishandled > inside attribute values.
Scoped CSS uses the scope ID from Vize.SFC.scope_id/2, passed to Vize, instead of one read back out of the compiled CSS.
Fixed
Hybrid server actions threw in the browser: they referenced __serverProps and triggerRef, which the generated module never defined.
Hybrid components re-render when LiveView sends new props. Only the first render used them.
Hybrid components keep working across server updates, and a prop change sends only the new props JSON instead of the whole tree.
Hybrid components get every prop the template or client-side code reads. Props used only in the template were left out, so they rendered empty once the client mounted.
Server actions send the values of refs and computeds instead of serialized Ref objects.
Before the client mounted, LiveView acted on hybrid phx-click attributes such as phx-click="pick(c)" and pushed the handler source to the server as an event name.
The hybrid bridge applies the initial props before mounting and unmounts the component when the hook is destroyed.
A QuickBEAM runtime leaked on every hybrid render.
Rendering never creates atoms. Reactive mount/3 turned every URL param into an atom, and change tracking, component props, v-for variables, and hybrid props and computeds converted names at render time, which PhoenixVapor.render/2 does for templates built at runtime.
Computeds may read computeds declared after them, and block-bodied computeds work in Reactive mode.
Expressions with methods that aren't evaluated in Elixir fall back to QuickBEAM. list.filter(fun) and list.map(fun) with a function reference returned the list unchanged, and methods such as padStart rendered nothing.
Scope and Vapor metadata attributes go after the root tag's name. They were inserted before the first >, which could be inside an attribute value such as title="a > b".
A <script lang="elixir"> block is left out of the hybrid client module, even after <script setup>.
Full-runtime LiveViews raise the JavaScript error from mount and events instead of a MatchError.
The Hex package contains only PhoenixVapor's own JavaScript. It included all of priv/js, so a locally built bundle such as reka-dialog.js would have been published.