Skip to content

v0.2.0

Release Date: January 19, 2026

This major release focuses on Hot Module Replacement (HMR) stability, introducing a professional mark-and-sweep cleanup system and enhanced DevTools with customizable shortcuts.


Pulse now uses a mark-and-sweep garbage collection approach for HMR:

  • Mark Phase: When HMR is detected, the generation counter increments and all units that re-register are marked as “alive”
  • Sweep Phase: After 100ms, units from previous generations that weren’t re-registered are automatically removed
  • Result: Only truly deleted units are cleaned up; units that remain in your code are preserved

Example:

// Initial load (generation 0)
const count = source(0, { name: "count" });
const user = source(null, { name: "user" });
// After HMR (generation 1)
// - Both units re-register and are marked with generation 1
// - No cleanup needed, both units preserved
// If you delete 'user' from code and save
// - Only 'count' re-registers with generation 2
// - 'user' (still at generation 1) is swept after 100ms

To ensure HMR stability, only units with explicit names are now visible in DevTools:

// ✅ Visible in DevTools
const count = source(0, { name: "count" });
const isEven = guard("is-even", () => count() % 2 === 0);
// ❌ Not visible in DevTools (but works perfectly)
const temp = source(0);
const check = guard(() => temp() > 5);

Why? Unnamed units create new object instances on every HMR reload, making stable tracking impossible. This is a fundamental JavaScript/HMR limitation shared by all state management libraries (Redux, Zustand, Jotai, etc.).

The keyboard shortcut for toggling DevTools is now fully customizable:

<!-- Default -->
<pulse-inspector></pulse-inspector>
<!-- Shortcut: Ctrl+M -->
<!-- Custom -->
<pulse-inspector shortcut="Ctrl+P"></pulse-inspector>
<pulse-inspector shortcut="Ctrl+Shift+D"></pulse-inspector>
<pulse-inspector shortcut="Alt+D"></pulse-inspector>

React:

import { PulseDevTools } from "@pulse-js/react/devtools";
<PulseDevTools shortcut="Ctrl+Shift+P" />;

Added a refresh button (🔄) to the DevTools header for manual registry refresh.


  • Mark-and-Sweep Cleanup: Intelligent HMR cleanup that only removes truly deleted units
  • Generation Tracking: Each unit is marked with a generation number for precise lifecycle management
  • Improved Registry: Simplified registration logic with better HMR detection
  • Performance: Eliminated unnecessary stack trace parsing overhead
  • Customizable Shortcuts: Support for any key combination via shortcut attribute
  • Refresh Button: Manual refresh capability for DevTools
  • Improved Tooltips: Dynamic tooltip showing current shortcut
  • Named Units Only: Cleaner, more stable unit tracking

React (@pulse-js/react v0.1.8)

  • Updated to use core 0.2.0 and tools 0.1.8
  • Shortcut prop support in PulseDevTools component

Vue (@pulse-js/vue v0.1.3)

  • Updated to use core 0.2.0 and tools 0.1.8

Svelte (@pulse-js/svelte v0.1.3)

  • Updated to use core 0.2.0

  • Updated DevTools Guide with named units requirement
  • Added examples of customizable shortcuts
  • Removed non-existent theme prop from documentation
  • Clarified HMR behavior and limitations

Breaking Change: Named Units for DevTools Visibility

Unnamed sources and guards will no longer appear in DevTools. To see them:

// Before (won't appear in DevTools)
const count = source(0);
const isValid = guard(() => count() > 0);
// After (visible in DevTools)
const count = source(0, { name: "count" });
const isValid = guard("is-valid", () => count() > 0);

Note: This only affects DevTools visibility. Unnamed units continue to work perfectly in your application.

Shortcut Changes

The default shortcut has changed from Ctrl+Shift+P to Ctrl+M. If you prefer the old shortcut:

<pulse-inspector shortcut="Ctrl+Shift+P"></pulse-inspector>

  • All 33 tests passing
  • Verified HMR stability with mark-and-sweep cleanup
  • Tested customizable shortcuts across different key combinations
  • Validated DevTools refresh functionality

  • @pulse-js/core: 0.2.0
  • @pulse-js/tools: 0.1.8
  • @pulse-js/react: 0.1.8
  • @pulse-js/vue: 0.1.3
  • @pulse-js/svelte: 0.1.3