Skip to content

feat(web): run the standalone player page on Vue Vapor - #404

Draft
a-wing wants to merge 8 commits into
mainfrom
feat/web-vapor
Draft

feat(web): run the standalone player page on Vue Vapor#404
a-wing wants to merge 8 commits into
mainfrom
feat/web-vapor

Conversation

@a-wing

@a-wing a-wing commented Jul 31, 2026

Copy link
Copy Markdown
Member

Summary

Experimental, stacked on #405 (which is stacked on #403) — merge only after those, and after the team is comfortable shipping a Vue 3.6 RC runtime (or after 3.6 goes stable).

  • Upgrades the workspace vue to 3.6.0-rc.2.
  • Dual-builds @binbat/whep-player-vue: default entry VDOM (Vue 3.5+), ./vapor entry Vapor-compiled via @vitejs/plugin-vue's features.vapor.
  • /tools/player.html and /tools/debugger.html run fully Vapor-compiled (createVaporApp).
  • The admin apps (liveion/liveman + web/shared) are also Vapor-compiled. @heroicons/vue / lucide-vue-next (VDOM-only icon libraries) are replaced by web/shared/components/icons/*.vue inline-SVG SFCs. runtime-dom is gone from the bundles; everything shares one runtime-vapor chunk.
  • Library peer range widened to ^3.5.0 || ^3.6.0-0 (a ^3.5.0-only range made pnpm link vue 3.5.22 into the package, silently breaking the Vapor build).

Size impact (measured, gzip, liveion bundles)

page main VDOM Vue (#403/#405) this PR (Vapor)
/tools/player.html 9.0 kB 31.4 kB 26.6 kB
/tools/debugger.html 39.8 kB 56.7 kB 52.4 kB
/ (admin) 60.8 kB 63.7 kB 76.6 kB ⚠️

Honest read: Vapor wins on the small tools pages, but at RC stage the shared runtime-vapor chunk grows from 21.0 kB to 38.1 kB gzip once the forms-heavy admin API surface is included (VDOM's runtime-dom is a fixed 25.9 kB), making the admin page a net size negative for now. Expect this to shrink as 3.6 matures; if size matters more than dogfooding, the admin commit (top one) can be dropped independently — the tools-page Vapor commits stand on their own.

Verification

  • pnpm -r build, pnpm run lint, pnpm exec biome check — all green.
  • Headless-Chromium e2e against live777: Vapor standalone player plays 1280x720; Vapor debugger subscribes/publishes (ICE State: connected); Vapor admin renders the streams table and plays the preview dialog — all screenshot-verified pixel-identical to the VDOM versions.

Notes

a-wing added 7 commits July 31, 2026 21:18
Split player-core into whep-core.ts (WhepPlaybackCore: plain getter
inputs, subscribe() state snapshots, no framework dependency) and a thin
Solid adapter (createWhepPlayback) that keeps the existing public API,
so current consumers work unchanged while other framework adapters can
be built on the same engine.
Vue 3 player library built on the framework-agnostic WhepPlaybackCore:
useWhepPlayback composable (MaybeRefOrGetter inputs, shallowRef state),
PlayerSurface / StatsForNerds / WhepPlayer components, written in the
Vapor-compatible script-setup subset but compiled for VDOM so it runs
on any Vue 3.5+ app today and in Vapor apps via interop later.
/tools/player.html in both liveion and liveman now mounts
StandaloneWhepPlayer from @binbat/whep-player-vue, driven by the same
URL query params (?id=&token=&autoplay&muted&controls&reconnect=) as
the retired Solid alone-player page. The whole web/alone-player
package is removed along with its build-chain entries.
Rewrite web/debugger from SolidJS to Vue 3 script-setup SFCs on top of
@binbat/whep-player-vue: useSearchParams composable replaces
@solidjs/router, logger becomes a ref-based useLogger, publish/QR logic
stays framework-free. player-core drops its Solid adapter and Solid
components and is now a pure framework-agnostic engine. solid-js,
@solidjs/router and vite-plugin-solid leave the workspace entirely.

Also fixes a pre-existing eslint no-unused-vars error in
scripts/whep_test.mjs.
Rewrite web/shared (components, hooks/composables, dash-player),
web/liveion and web/liveman from Preact/preact-compat to Vue 3
script-setup SFCs. react-daisyui is replaced by plain daisyui classes
in templates, @heroicons/react and lucide-react by their Vue
counterparts, TokenContext by provide/inject, and the root typecheck
now runs vue-tsc. The dead web/shared/tools/player is deleted.

Preact, preact-router, react-daisyui, @heroicons/react, lucide-react
and @preact/preset-vite leave the workspace; the entire web UI is now
Vue 3.

Verified: pnpm -r build, lint, biome all green; headless-Chromium e2e
shows the streams table with live stats and plays the preview dialog
video.
Upgrade vue to 3.6.0-rc.2 and dual-build @binbat/whep-player-vue from
the same sources: the default entry stays VDOM-compiled (Vue 3.5+),
while a new ./vapor entry is compiled in Vapor mode via plugin-vue's
features.vapor. /tools/player.html in liveion and liveman now mounts
createVaporApp with the Vapor build; the debugger page keeps the VDOM
build (running fine on the 3.6 runtime).

Widen the library's vue peer range to ^3.5.0 || ^3.6.0-0: with ^3.5.0
only, pnpm linked vue 3.5.22 into the package, and its compiler-sfc
silently ignored the vapor flag, emitting VDOM code for the 'vapor'
build.

Verified in headless Chromium against live777: the Vapor page plays
the 1280x720 test stream and the debugger page still works.
The debugger's components were already written in the Vapor-compatible
subset, so flip plugin-vue's features.vapor on its build, alias the
player-vue import to the ./vapor entry, and mount with createVaporApp.
The liveion/liveman bundles no longer pull in runtime-dom at all: both
Vue tools pages share runtime-vapor (21.0 kB gzip vs 25.9 kB for
runtime-dom), bringing the debugger page to 52.4 kB gzip and the
standalone player page to 26.6 kB gzip (second page visit on the same
origin only pays its small entry chunk).

Verified in headless Chromium: WHEP subscribe plays 1280x720 with
render-FPS overlay, WHIP publish reaches ICE State: connected.
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
see 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Replace @heroicons/vue and lucide-vue-next (VDOM-compiled icon
libraries, unusable in a pure Vapor app) with web/shared/components/icons/*.vue
inline-SVG SFCs copied verbatim from the source packages, flip
features.vapor in the shared vite config, and mount liveion/liveman
with createVaporApp. Admin, debugger and player pages now share a
single runtime-vapor chunk.

Honest size note: at RC stage the admin page grows (63.7 -> 76.6 kB
gzip) — the shared runtime-vapor chunk balloons from 21.0 to 38.1 kB
gzip once the forms-heavy admin API surface is included, while VDOM's
runtime-dom is a fixed 25.9 kB. Vapor still wins on the small tools
pages; revisit after Vue 3.6 stable.

Verified in headless Chromium: admin streams table renders, preview
dialog plays 1280x720 WHEP video, layouts pixel-identical.
@a-wing
a-wing changed the base branch from refactor/web-solid-to-vue to refactor/web-admin-vue July 31, 2026 16:38
Base automatically changed from refactor/web-admin-vue to refactor/web-solid-to-vue August 8, 2026 05:31
Base automatically changed from refactor/web-solid-to-vue to main August 8, 2026 06:00
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.

1 participant