Repository navigation
Declare data the browser changes with defineModel, not prop writes - #17
Merged
Merged
Conversation
A hybrid server action wrote props.x, which Vue's types and runtime both
reject; it worked only because the client codegen rewrote the
assignment. Data the browser changes and the server owns is now a model,
Vue's construct for it: defineModel("contacts") is assigned by the
LiveView, read as .value in the script, and writing it is a server action.
The action's body runs in the browser as written, so a model write
updates the mount's props at once through its update: listener. Then the
action goes to the server, unless the body returned or threw first, so a
guard validates in the browser. Once the server has handled it, the
bridge reapplies data-pv-props, so a change the server declined goes
away. Props an action reads are sent to the browser.
Writing props.x, or a bare prop name the script never binds, is a
compile error pointing at defineModel; a model must be named after its
variable. A server action body with an early return was parsed as a
script, failed, and silently became a client handler; bodies now parse
as functions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Breaking: hybrid components declare data the browser changes, and the server owns, with Vue's
defineModelinstead of writing to props.Why
A server action wrote
props.contacts = .... Vue rejects that in its types (props are read-only, TS2540) and at runtime; it worked only because the client codegen rewrote the assignment. Hybrid components therefore couldn't type-check, and the convention taught something Vue forbids.What changes
defineModel("name")is assigned by the LiveView under that name, sent to the browser with the props, and read as.valuein the script, including in computeds the server evaluates. A model must be named after its variable. A function that writes a model is a server action, as one that wrote a prop was.update:listener. Then the action goes to the server through a newbridge.action/2. Areturnor athrowfirst sends nothing, so a guard validates in the browser.data-pv-props. An assign the server left unchanged therefore replaces the optimistic value; before, it stayed on screen.handle_event/3reads it. The guide says so.props.x, or a barexfor a prop the script never binds, is a compile error at its line, pointing atdefineModel.JS.FreeNames.occurrences/1finds the unbound writes, so a parameter named like a prop is fine.Docs
The Hybrid guide's Server actions section, ARCHITECTURE,
docs/hybrid-architecture.md, and CHANGELOG (Breaking changes, Fixed).Tests
mix lintclean;mix test --include e2e: 373 passed.