v1.6.0 — CODE CHANGE: the injected shim now primes globalThis.VUE from the
consumer's 'vue' (via a companion virtual module that evaluates before
'vapor-chamber') so the lib's synchronous Vue/Vapor detection works in
Vite dev. Before this, the shim's top-of-module injection guaranteed
vapor-chamber evaluated before any user code could prime detection, and
the async probe (bare-specifier dynamic import) always fails in
browsers — so createVaporChamberApp() threw on every dev page load
whenever this plugin was active. Found by browser-verifying the
vapor-sfc example. Non-Vue consumers unaffected (the priming module is
emitted only when 'vue' resolves).
v1.5.0 — Vue 3.6.0-beta.14 HMR alignment:
• dedupe HMR parent reloads (hmr: dedupe HMR parent reloads) — Vue now
deduplicates parent reload events at the runtime level; the dispose
shim mirrors this with a per-cycle guard so the bus is persisted at
most once per HMR update regardless of how many parent reload events
fire.
• align child/parent reload timing (hmr: align child component HMR
reload with parent rerender) — child component HMR reload is now
synchronised with the parent rerender; bus restoration happens after
the full parent subtree has settled.
• preserve setup effects (runtime-vapor: preserve setup effects during
hmr rerender) — watchers and computed effects created in setup() are
maintained across HMR rerenders; bus handlers registered via
watchEffect inside setup() survive a hot reload without re-registration.
• restore HMR context on errors (runtime-vapor: restore hmr context on
errors) — HMR context is recovered when an error occurs mid-reload;
the shim wraps bus persistence in try/catch so a failed getCommandBus()
call doesn't leave the module in an unrecoverable state.
• update app instance on root reload (runtime-vapor: update app instance
on root hmr reload) — the app instance on the root component is
refreshed after a root HMR cycle; callers of createVaporChamberApp()
no longer need to re-acquire the app reference after a root reload.
v1.1.0 — Vapor↔VDOM mode switching: tracks __vapor state during HMR reloads
so components switching between Vapor and VDOM modes preserve bus state.
v0.5.0 — State-preserving hot module replacement.
Preserves the shared command bus (handlers, plugins, hooks) across Vite HMR
updates so that application state survives component hot-reloads.
Without this plugin, each HMR update re-creates the bus from scratch,
clearing all registered handlers and registered state.
Tested against:
• Vite ≥ 7.0.0 (programmatic build API + library mode)
• @vitejs/plugin-vue ≥ 5.0.0 (Vue 3.6 Vapor SFC support — earlier
plugin-vue versions only handle 3.5 VDOM and silently skip vapor blocks)
• Vue ≥ 3.5.0 (composables) or ≥ 3.6.0-beta.14 (full Vapor surface)
If you're on plugin-vue v4 the HMR plugin still works for VDOM SFCs but
you'll miss Vapor support entirely — Vapor <script setup vapor> blocks
fall back to the VDOM compiler. Upgrade plugin-vue alongside Vue 3.6.
// main.ts — no changes required; HMR is transparent import { createCommandBus } from'vapor-chamber' constbus = createCommandBus() bus.register('cartAdd', handler) // After HMR: handler is still registered, state is preserved
vapor-chamber - Vite HMR plugin
v1.6.0 — CODE CHANGE: the injected shim now primes globalThis.VUE from the consumer's 'vue' (via a companion virtual module that evaluates before 'vapor-chamber') so the lib's synchronous Vue/Vapor detection works in Vite dev. Before this, the shim's top-of-module injection guaranteed vapor-chamber evaluated before any user code could prime detection, and the async probe (bare-specifier dynamic import) always fails in browsers — so createVaporChamberApp() threw on every dev page load whenever this plugin was active. Found by browser-verifying the vapor-sfc example. Non-Vue consumers unaffected (the priming module is emitted only when 'vue' resolves). v1.5.0 — Vue 3.6.0-beta.14 HMR alignment: • dedupe HMR parent reloads (hmr: dedupe HMR parent reloads) — Vue now deduplicates parent reload events at the runtime level; the dispose shim mirrors this with a per-cycle guard so the bus is persisted at most once per HMR update regardless of how many parent reload events fire. • align child/parent reload timing (hmr: align child component HMR reload with parent rerender) — child component HMR reload is now synchronised with the parent rerender; bus restoration happens after the full parent subtree has settled. • preserve setup effects (runtime-vapor: preserve setup effects during hmr rerender) — watchers and computed effects created in setup() are maintained across HMR rerenders; bus handlers registered via watchEffect inside setup() survive a hot reload without re-registration. • restore HMR context on errors (runtime-vapor: restore hmr context on errors) — HMR context is recovered when an error occurs mid-reload; the shim wraps bus persistence in try/catch so a failed getCommandBus() call doesn't leave the module in an unrecoverable state. • update app instance on root reload (runtime-vapor: update app instance on root hmr reload) — the app instance on the root component is refreshed after a root HMR cycle; callers of createVaporChamberApp() no longer need to re-acquire the app reference after a root reload. v1.1.0 — Vapor↔VDOM mode switching: tracks __vapor state during HMR reloads so components switching between Vapor and VDOM modes preserve bus state. v0.5.0 — State-preserving hot module replacement.
Preserves the shared command bus (handlers, plugins, hooks) across Vite HMR updates so that application state survives component hot-reloads.
Without this plugin, each HMR update re-creates the bus from scratch, clearing all registered handlers and registered state.
Tested against: • Vite ≥ 7.0.0 (programmatic build API + library mode) • @vitejs/plugin-vue ≥ 5.0.0 (Vue 3.6 Vapor SFC support — earlier plugin-vue versions only handle 3.5 VDOM and silently skip vapor blocks) • Vue ≥ 3.5.0 (composables) or ≥ 3.6.0-beta.14 (full Vapor surface)
If you're on plugin-vue v4 the HMR plugin still works for VDOM SFCs but you'll miss Vapor support entirely — Vapor
<script setup vapor>blocks fall back to the VDOM compiler. Upgrade plugin-vue alongside Vue 3.6.Example
Example