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

@alekstar79/reactive-event-system

v1.0.1

Published

High-performance reactive event system with batched updates, middleware support, and streaming capabilities

Readme

Reactive Event System

NPM GitHub repo Typescript License Version Coverage

High-performance reactive event bus with batched updates, middleware support, and streaming capabilities. Built for TypeScript with full type safety and ES2024 compatibility.

Reactive Event System

Features

  • 🚀 High Performance: Batched reactive updates for minimal re-renders
  • 🔄 Reactive: Seamless integration with reactive state management
  • 🔗 Middleware Pipeline: Flexible event processing with global and event-specific middleware
  • 📡 Event Streaming: Convert events to reactive streams with built-in metrics
  • ⏱️ Promise-based: waitFor() method for async event handling with timeout support
  • 🔀 Event Piping: Route events from one bus to another with optional transformation
  • 📊 Metrics: Built-in monitoring with reactive metrics tracking
  • 📦 Tree-shakeable: Fully modular, ES2022+ compatible
  • 💪 Type Safe: Complete TypeScript support with generics

Installation

npm

npm install @alekstar79/reactive-event-system

yarn

yarn add @alekstar79/reactive-event-system

pnpm

pnpm add @alekstar79/reactive-event-system

Quick Start

Basic Usage

import ReactiveEventSystem from '@alekstar79/reactive-event-system'

// Create a bus instance
const bus = new ReactiveEventSystem()

// Subscribe to events
bus.on('message', (data) => {
  console.log('Message received:', data)
})

// Emit events
bus.emit('message', { text: 'Hello, World!' })

// Unsubscribe (automatic)
const unsubscribe = bus.on('message', (data) => {
  console.log('Handler 1:', data)
})
unsubscribe()

One-time Events

// Listen for event only once
bus.once('connected', (data) => {
  console.log('Connected:', data)
})

// Alternatively, with unsubscribe function
const unsubscribe = bus.once('connected', (data) => {
  console.log('Connected:', data)
})

Promise-based Event Waiting

// Wait for specific event with timeout
try {
  const user = await bus.waitFor('authComplete', 5000)
  console.log('Authenticated:', user)
} catch (error) {
  console.log('Auth timeout')
}

// Wait without timeout
const data = await bus.waitFor('dataLoaded')

Reactive Streams

import { effect } from '@alekstar79/reactive-event-system'

// Create a stream from events
const messageStream = bus.stream('messages')

// React to stream updates
effect(() => {
  console.log('Latest message:', messageStream.state.value)
  console.log('Total messages:', messageStream.state.count)
})

// Subscribe to stream
const unsubscribe = messageStream.subscribe((msg) => {
  console.log('Stream listener:', msg)
})

// Cleanup
messageStream.destroy()

Middleware Pipeline

// Global middleware (all events)
bus.use('*', (data, event) => {
  console.log(`Event: ${event}`, data)
  return data
})

// Event-specific middleware
bus.use('userAction', (data, event) => {
  if (!data.userId) {
    throw new Error('userId is required')
  }
  // Transform data
  return {
    ...data,
    timestamp: Date.now(),
    processed: true
  }
})

// Multiple middleware chains
const unsubscribe = bus.use('userAction', (data) => {
  return { ...data, validated: true }
})

Event Piping

const sourceBus = new ReactiveEventSystem()
const targetBus = new ReactiveEventSystem()

// Pipe events from source to target
const unpipe = sourceBus.pipe('data', targetBus)

// Pipe with event name transformation
const unpipeRenamed = sourceBus.pipe('input', targetBus, 'processedInput')

// Stop piping
unpipe()

Metrics and Monitoring

import ReactiveEventSystem, { effect } from '@alekstar79/reactive-event-system'

// Enable metrics on initialization
const bus = new ReactiveEventSystem({ enableMetrics: true })

// Get metrics object
const metrics = bus.getMetrics()

// Monitor metrics reactively
effect(() => {
  console.log('Total events emitted:', metrics.state.totalEventsEmitted)
  console.log('Last event:', metrics.state.lastEmittedEvent)
  console.log('Active listeners:', metrics.state.activeListeners)
  console.log('Total listeners:', metrics.totalListeners())
  console.log('Event names:', metrics.events())
})

Error Handling

// Custom error handler
const bus = new EventBusReactiveEventSystem({
  errorHandler: (error, event, listener) => {
    console.error(`Error in listener for "${event}":`, error.message)
    // Custom error reporting, logging, etc.
  }
})

// Listen for events
bus.on('test', () => {
  throw new Error('Something went wrong')
})

// Event is still emitted, error is handled
bus.emit('test', {})

Utility Methods

// Check listener count
const count = bus.listenerCount('message')
console.log('Listeners:', count)

// Check if event has listeners
if (bus.hasListeners('message')) {
  bus.emit('message', { text: 'Someone is listening' })
}

// Get all event names
const eventNames = bus.eventNames()
console.log('Events:', eventNames)

// Remove all listeners for specific event
bus.removeAllListeners('message')

// Remove all listeners for all events
bus.removeAllListeners()

// Cleanup resources
bus.destroy()

Typed Events

interface UserEventData {
  userId: string
  username: string
  email: string
}

// Create typed bus
const userBus = new ReactiveEventSystem<UserEventData>()

// TypeScript enforces correct data structure
userBus.on('userCreated', (data) => {
  console.log(data.userId) // ✓ OK
  console.log(data.username) // ✓ OK
  // console.log(data.unknown) // ✗ Error: Property 'unknown' does not exist
})

userBus.emit('userCreated', {
  userId: '123',
  username: 'john',
  email: '[email protected]'
})

API Reference

ReactiveEventSystem

Main class for event bus functionality.

Constructor

constructor(options?: {
  enableMetrics?: boolean
  errorHandler?: (error: Error, event: string, listener: Function) => void
})

Methods

  • on(event, listener, options?): Subscribe to event
  • once(event, listener, options?): Subscribe to event once
  • off(event, listener): Unsubscribe from event
  • emit(event, data): Emit event to all listeners
  • listenerCount(event): Get listener count for event
  • removeAllListeners(event?): Remove all listeners
  • eventNames(): Get all event names
  • hasListeners(event): Check if event has listeners
  • use(event, middleware): Add middleware
  • stream(event): Create reactive stream
  • getMetrics(): Get metrics object
  • waitFor(event, timeout?): Wait for event (Promise)
  • pipe(fromEvent, toEmitter, toEvent?): Pipe events
  • destroy(): Cleanup resources

TypeScript Support

Full TypeScript support with complete type definitions included.

import ReactiveEventSystem, { EventSystemMetrics, EventStream, EventMiddleware } from '@alekstar79/reactive-event-system'

interface AppEvents {
  ready: { timestamp: number }
  error: { message: string }
  data: { value: string }
}

type AppBus = ReactiveEventSystem<AppEvents>

Browser Support

  • Chrome: ✓ Latest
  • Firefox: ✓ Latest
  • Safari: ✓ Latest
  • Edge: ✓ Latest

Requires ES2024 support or transpilation.

Performance

  • Batched reactive updates minimize re-renders
  • WeakMap-based cleanup prevents memory leaks
  • Set-based listener storage for O(1) operations
  • Minimal overhead for event emission

Testing

npm test
npm run test:coverage
npm run test:ui

📊 Test Coverage

| File | % Stmts | % Branch | % Funcs | % Lines | |-----------|---------|----------|---------|---------| | All files | 79.31 | 75 | 69.09 | 80.48 | | index.ts | 79.31 | 75 | 69.09 | 80.48 |

Contributing

Contributions are welcome! Please read our contributing guidelines first.

License

MIT © 2025 @alekstar79

Related Projects

Changelog

See CHANGELOG.md for release history.

Security

For security issues, please email instead of using the issue tracker.