npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pulse-state-z

v0.1.28

Published

Event-driven reactive state runtime with deterministic propagation and dependency graphs.

Readme

⚡ pulse-state-z

NPM Downloads Bundle Size

LIVE EXAMPLE

Minimal event-driven reactive state runtime built on top of eventbus-z.

pulse-state-z turns event streams into a deterministic reactive state graph with batching, derived state, and automatic dependency tracking.

eventbus-z emits → reactive graph propagates → derived state updates


Why pulse-state-z?

  • ✅ Event-driven state updates (powered by eventbus-z)
  • ✅ Fine-grained reactive graph
  • ✅ Derived & computed state
  • ✅ Automatic dependency tracking
  • ✅ Batched updates
  • ✅ Async state actions
  • ✅ Selector subscriptions
  • ✅ Combine multiple stores
  • ✅ Cycle detection
  • ✅ Glitch-free propagation
  • ✅ Optional persistence

Mental Model

Every store emits an event when its value changes.

signal.set()
   ↓
eventbus-z emit
   ↓
reactive graph propagation
   ↓
computed / derived recompute
   ↓
subscribers notified

The dependency graph guarantees deterministic and glitch-free updates.


Installation

npm install pulse-state-z

Quick Example

import { signal, map, computed } from "pulse-state-z"

const count = signal(0)

const double = map(count, v => v * 2)

const total = computed(() => count() * 10)

count.set(5)

console.log(count())   // 5
console.log(double())  // 10
console.log(total())   // 50

Creating a Store

import { signal } from "pulse-state-z"

const counter = signal(0)

counter.set(1)

console.log(counter()) // 1

Updating State

counter.update(v => v + 1)

Async updates:

await counter.asyncUpdate(async v => {
  const next = await fetchValue()
  return v + next
})

Subscribe to Changes

counter.subscribe(() => {
  console.log("value:", counter())
})

Or listen directly to value changes:

counter.onChange(v => {
  console.log("value:", v)
})

Batch Updates

Batch multiple updates into a single propagation cycle.

// transaction
import { batch } from "pulse-state-z"

batch(() => {
  counter.set(1)
  counter.set(2)
  counter.set(3)
})

Subscribers run only once after the batch finishes.


Derived State with map

Create derived values from one or more stores.

import { map } from "pulse-state-z"

const double = map(counter, v => v * 2)

console.log(double())

Multiple sources:

const a = signal(2)
const b = signal(3)

const sum = map([a, b], (x, y) => x + y)

console.log(sum()) // 5

Computed

Dependencies are tracked automatically.

import { computed } from "pulse-state-z"

const count = signal(1)

const expensive = computed(() => {
  console.log("compute")
  return count() * 100
})

count.set(2)
count.set(3)
count.set(4)

console.log(expensive())

Computed values are lazily evaluated.

They only recompute when accessed, not when dependencies change. This avoids unnecessary work in large reactive graphs.


Selector

Create lightweight derived values without creating a full reactive node.

import { selector } from "pulse-state-z"

const double = selector(counter, v => v * 2)

console.log(double())

Selectors recompute only when subscribed.


Effect

Run a reactive side-effect that automatically tracks dependencies.

import { signal, effect } from "pulse-state-z"

const price = signal(100)
const qty = signal(2)

effect(() => {
  console.log("total:", price() * qty())
})
  • Any signal accessed inside the function becomes a dependency.
  • The effect re-runs automatically when those signals change.

Watch

Watch a specific signal and react to its changes.

import { signal, watch } from "pulse-state-z"

const count = signal(0)

watch(count, v => {
  console.log("count:", v)
})

count.set(1)
count.set(2)

watch is useful when you want to observe one signal directly without creating a full reactive computation.


Watch Multiple Signals

const price = signal(10)
const qty = signal(2)

watch([price, qty], ([p, q]) => {
  console.log("total:", p * q)
})

Untrack

Read a signal without creating a dependency.

Useful for logging, debugging, or reading values that should not trigger reactive updates.

import { signal, effect, untrack } from "pulse-state-z"

const count = signal(1)

effect(() => {
  console.log(
    "count:",
    count(),
    "time:",
    untrack(() => Date.now())
  )
})

Only count is tracked as a dependency.


Difference

| API | Purpose | |----------- |--------------------------- | | effect() | auto-track dependencies | | watch() | observe specific signal(s) |


Combine Multiple Stores

import { signal, combine } from "pulse-state-z"

const user = signal({ name: "A" })
const count = signal(0)

const state = combine({
  user,
  count
})

console.log(state())

Combined state updates when any dependency changes.


Persistence

Persist state in localStorage.

const counter = signal(0, {
  persistKey: "counter"
})

State is restored automatically on load.


Comparison

| Criteria | pulse-state-z | Zustand | Redux | Recoil | | ----------------------- | ------------------------ | --------------- | --------------------- | ------------- | | Core model | Event + reactive graph | Mutable store | Reducer state machine | Atom graph | | React required | ❌ No | ⚠️ Mostly | ⚠️ Mostly | ✅ Yes | | Outside React | ✅ Native | ⚠️ Limited | ✅ Yes | ❌ No | | Derived state | ✅ computed / autoComputed| ⚠️ selector | ⚠️ memo selector | ✅ selector | | Signal tracking | ✅ autoComputed | ❌ | ❌ | ⚠️ partial | | Batch update | ✅ built-in | ⚠️ React batch | ⚠️ middleware | ⚠️ React | | Glitch-free propagation | ✅ graph propagation | ❌ | ❌ | ⚠️ sometimes | | Event driven | ✅ | ❌ | ⚠️ action dispatch | ❌ | | Persistence | ✅ built-in | ⚠️ middleware | ⚠️ middleware | ❌ | | Cycle detection | ✅ | ❌ | ❌ | ❌ | | Bundle size | small | ~1kb | 6-10kb | 15kb+ |


Architecture

signal()
   │
   ▼
eventbus-z emission
   │
   ▼
Reactive graph propagation
   │
   ▼
map / computed recompute
   │
   ▼
Subscribers notified

The runtime guarantees:

  • deterministic propagation
  • cycle detection
  • glitch-free updates

Ecosystem

pulse-state-z is designed to work naturally with eventbus-z.

eventbus-z provides the event transport layer,
while pulse-state-z builds the reactive dependency graph runtime on top.

pulse-state-z is part of a growing eventbus-driven ecosystem and works naturally alongside runtimes like intentx-core-z.


Minimal API Surface

signal • map • computed • effect • watch • combine • selector • batch

A small set of primitives for building event-driven reactive state graphs.


License

MIT