Skip to content

chore: upgrade Vue to 3.6.0-rc.1#137

Merged
doodlewind merged 3 commits into
pocket-stack:mainfrom
zhiyuanzmj:chore/vue3.6.0-rc.1
Jul 21, 2026
Merged

chore: upgrade Vue to 3.6.0-rc.1#137
doodlewind merged 3 commits into
pocket-stack:mainfrom
zhiyuanzmj:chore/vue3.6.0-rc.1

Conversation

@zhiyuanzmj

Copy link
Copy Markdown
Contributor
  1. Upgrade vue-jsx-vapor to 3.2.19 to support Vue@3.6.0-rc.1.
  2. Use a functional component instead of defineVaporComponent so you can access props directly instead of attrs, without needing to define runtime props.
  3. Fixed an undefined node.children error in devtools.ts for Vue Vapor support.
    image

Bump Vue packages to 3.6.0-rc.1 and vue-jsx-vapor to 3.2.19.
Update bun.lock and package.json accordingly. Adjust demos to
remove defineVaporComponent imports and adapt component props/usage.
Update WASI CDN version for compiler-rs and add a guard when
iterating node.children in devtools.
Copilot AI review requested due to automatic review settings July 20, 2026 20:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the Vue Vapor stack to align with Vue 3.6.0-rc.1 and updates PocketJS’s Vue Vapor demo components to use plain functional component syntax (direct props access) instead of defineVaporComponent, alongside a small DevTools robustness fix for Vue Vapor tree serialization.

Changes:

  • Bump vue, @vue/compiler-vapor, and vue-jsx-vapor to versions compatible with Vue 3.6.0-rc.1.
  • Refactor multiple Vue Vapor demos to functional components that read from props instead of attrs.
  • Prevent a node.children undefined crash during DevTools tree snapshotting for Vue Vapor.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/devtools.ts Adds a defensive guard to avoid crashing when children is missing during tree serialization/counting.
site/playground/vue-vapor-wasi.ts Updates the CDN version for the browser WASI shim to match the upgraded vue-jsx-vapor compiler package.
package.json Upgrades Vue/Vapor-related dependency versions to 3.6.0-rc.1 / 3.2.19.
bun.lock Lockfile updates reflecting the upgraded Vue/Vapor dependency graph.
demos/stats/app.vue-vapor.tsx Switches demo subcomponents to functional components; one small simplification needed for frame prop usage.
demos/settings/app.vue-vapor.tsx Switches to functional components, but currently introduces a double-invocation bug in Toggle’s onToggle handling.
demos/library/app.vue-vapor.tsx Converts demo subcomponents to functional components using direct props.
demos/hero/app.vue-vapor.tsx Converts Stat to a functional component and removes defineVaporComponent usage.
demos/hero-vue-vapor/app.tsx Simplifies the app export to a functional component style consistent with Vue Vapor usage.
demos/gallery/app.vue-vapor.tsx Converts Loading, TileGrid, and Page to functional components using direct props.
demos/cards/app.vue-vapor.tsx Converts Detail to a functional component using direct props.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread demos/settings/app.vue-vapor.tsx Outdated
const themeName = () => propValue(attrs.themeName as ThemeName | (() => ThemeName));
const onToggle = () => callbackProp(attrs.onToggle as (() => void) | (() => () => void));
const themeName = () => propValue(props.themeName as ThemeName | (() => ThemeName));
const onToggle = () => callbackProp(props.onToggle as (() => void) | (() => () => void));
Comment thread demos/stats/app.vue-vapor.tsx Outdated
const Systems = defineVaporComponent((_props: { frame: number }, { attrs }) => {
const frame = () => (typeof attrs.frame === "function" ? (attrs.frame as () => number)() : (attrs.frame as number));
const Systems = (props: { frame: number }) => {
const frame = () => (typeof props.frame === "function" ? (props.frame as () => number)() : (props.frame as number));
…lve props

With vue-jsx-vapor 3.2.19 functional components, props reach the component
already resolved (the attrs proxy invokes the compiler's getters), so the
propValue/callbackProp indirection is dead weight — and callbackProp's eager
zero-arg probe actually INVOKED the resolved handler, firing Settings'
onToggle twice per press (verified in the deterministic sim: one CIRCLE
press produced two parent callback invocations, canceling the toggle).

Access props directly everywhere, call callbacks exactly once, and drop the
now-impossible function branches from the prop types.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@doodlewind

Copy link
Copy Markdown
Collaborator

Verified both Copilot findings empirically and pushed a follow-up commit (53ce906) addressing them.

How it was verified: built a minimal probe app using the exact callbackProp pattern and ran it in the deterministic sim host with a scripted button press, counting invocations through globals (the UI tree lags in the sim, so counters are the ground truth):

  • typeof props.onToggle inside a functional component → "function" — the vapor attrs proxy resolves the compiler's prop getters before the component sees them (instance.props === instance.attrs for function components in @vue/runtime-vapor, and attrs get runs resolveSource).
  • One CIRCLE press → onToggle fired twice: callbackProp's zero-arg probe invoked the already-resolved handler, then the onToggle()() call site invoked it again. For Settings this cancels the parent's sfx/vibration flip while the knob animates — a real double-fire, exactly as flagged.
  • After the fix (direct props.onToggle()): one press → one invocation.

The fix drops the now-dead propValue/callbackProp indirection across the four demos that still carried it (settings, gallery, cards, stats) and calls callbacks exactly once, which also removes the dead typeof props.frame === "function" branch in stats. All demo variants rebuild cleanly (solid + vue-vapor), the full test suite passes, and settings/gallery/cards/stats/library vue-vapor bundles run a scripted input journey in the sim without errors.

Thanks for the upgrade — the functional-component form is a real simplification. 🙏

@doodlewind
doodlewind merged commit a9788c7 into pocket-stack:main Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants