An open API service indexing awesome lists of open source software.

https://github.com/orelnatan/ngx-event-bus-lib


https://github.com/orelnatan/ngx-event-bus-lib

Last synced: about 16 hours ago
JSON representation

Awesome Lists containing this project

README

          



Ngx Event Bus

# ngx-event-bus

[![CircleCI](https://circleci.com/gh/orelnatan/ngx-event-bus-lib/tree/master.svg?style=svg)](https://app.circleci.com/pipelines/github/orelnatan/ngx-event-bus-lib)
[![codecov](https://codecov.io/gh/orelnatan/ngx-event-bus-lib/graph/badge.svg?token=4GAKYYNREF)](https://codecov.io/gh/orelnatan/ngx-event-bus-lib)
[![SSR](https://img.shields.io/badge/SSR-support-brightgreen)](https://www.npmjs.com/package/on-ngx-event-bus)
[![NPM Version](https://img.shields.io/npm/v/on-ngx-event-bus?color=blue)](https://www.npmjs.com/package/on-ngx-event-bus)
[![npm package size](https://img.shields.io/npm/unpacked-size/on-ngx-event-bus?color=orange)](https://www.npmjs.com/package/on-ngx-event-bus)
[![License](https://img.shields.io/npm/l/on-ngx-event-bus?color=blue)](https://github.com/orelnatan/ngx-event-bus-lib/blob/master/LICENSE)
[![Angular](https://img.shields.io/badge/Angular-21+-dd0031)](https://angular.dev)
[![Downloads](https://img.shields.io/npm/dm/on-ngx-event-bus?color=blue)](https://www.npmjs.com/package/on-ngx-event-bus)

**A lightweight, fully-tested, type-safe global event bus for Angular — powered by decorators, pure functions, and zero shared state.**

Broadcast strongly-typed events anywhere in your app and react to them declaratively —
without services, DI, providers, RxJS, Signals, or tight coupling.


⚠️ The on- prefix is used solely to avoid a naming conflict on npm and has no functional meaning.

## Motivation

In many Angular applications, **components that are completely unrelated still need to communicate**.

When the app is not built around a state-management solution, a common approach is to introduce a shared service —
usually based on RxJS `Subject`'s or Signals — and use it as a communication bridge.

This typically requires:
- Services, providers, and dependency injections
- RxJS tools or Signals
- Manual lifecycle handling to avoid memory leaks (in the case of RxJS)

`ngx-event-bus` takes a different approach.

It is built on **native JavaScript events**, automatically adds and removes event listeners to prevent **memory leaks**, and requires **no services, no DI, and no module setup or imports**. Event handling is simple, declarative, and free from shared state.

## Compatibility

✅ **Angular support:** Angular **v9 and above**

Supports **all Angular entities**:

- Components
- Directives
- Services
- Pipes

## Quick Start 🚀

## Install
```bash
# npm
npm install on-ngx-event-bus

# yarn
yarn add on-ngx-event-bus

# pnpm
pnpm add on-ngx-event-bus
```

## Usage

### Broadcasting an event 🛜​
```ts
import { broadcast, GEvent } from "on-ngx-event-bus";

publish(): void {
broadcast(
new GEvent("MY_EVENT", {
metadata: "My event data..."
})
);
}
```

- The event's payload can be **any type of data** — primitives, objects, functions, and more. (If no payload is provided, the default is null)

---

### Intercepting an event 📡
```ts
import { Component } from "@angular/core";
import { Interceptor, intercept } from "on-ngx-event-bus";

@Interceptor([
{ type: "MY_EVENT", action: "handleEvent" }
])
@Component({
selector: "app-home",
template: `Home`
})
export class HomeComponent {
constructor() {
intercept(this);
}

handleEvent(payload: { metadata: string }): void {
console.log("Event intercepted: ", payload);
}
}
```
- ⚠️ Mandatory: Always call `intercept(this)` in the constructor to activate the `@Interceptor`.

- The `@Interceptor` decorator can intercept and handle **any number of events**, without limits.

## 🎯 Targeted Events

By default, events are **broadcast globally** — each interceptor listening to the same event type will receive them.

However, in some scenarios you may want **only specific listeners** to react to an event, even if multiple interceptors are registered for the same type. To support this, events can be optionally sent with a **`key`** (`string`).

### Broadcasting a targeted event 🛜​

```ts
publish(): void {
broadcast(
new GEvent("MY_EVENT", {
metadata: "My event data..."
}, "BUS::MY_EVENT::A9F3-77XQ") // 🔑​
);
}
```

### Intercepting a targeted event 📡

```ts
@Interceptor([
{ type: "MY_EVENT", action: "handleTargetedEvent", key: "BUS::MY_EVENT::A9F3-77XQ" }
])
@Component({
selector: "app-home",
template: `Home`
})
export class HomeComponent {
constructor() {
intercept(this);
}

handleTargetedEvent(): void {
console.log("Will be triggered only if the key matches...");
}
}
```
- Events broadcast with a mismatched key will be **rejected** by the `@Interceptor` ❌

## Advanced Usage ⚡

`ngx-event-bus` supports **fully-typed events** in 3 different levels, from quick-and-loose to fully enforced best practices.

---

### 1️⃣ Loose / Quick Usage
```ts
broadcast(new GEvent("MY_EVENT", {
metadata: "Quick, untyped payload"
}));
```
- ✅ Fast — minimal setup, just fire-and-forget.
- ✅ Flexible — any shape of payload is allowed.
- ❌ No type safety (developer choice)

### 2️⃣ Generic enforce - Strongly Typed
```ts
broadcast(
new GEvent<"MY_EVENT", { metadata: string }>("MY_EVENT", {
metadata: "Payload and event name are generic enforced."
})
);
```
Or even smarter, with Enums/types and interfaces

```ts
enum MyEventTypes {
MyEvent = "MY_EVENT"
}

interface MyEventPayload {
metadata: string;
}

broadcast(
new GEvent(
MyEventTypes.MyEvent, {
metadata: "Payload and event name are generic enforced."
})
);
```
- ✅ Payload enforced — TypeScript ensures payload shape is correct.
- ✅ Event names centralized — reduces typos and keeps event names consistent.
- ✅ Better developer experience — IDE autocompletion works.
- ❌ Event–payload relationship not fully enforced — nothing prevents using the wrong payload with a given event type.

### 3️⃣ Fully Enforced, Best Practice 🥇
By extending the `GEvent` class, you can create your own fully enforced events. This ensures **both the event type and its payload are strictly typed**, making your code refactor-safe and perfect for large apps.

```ts
import { GEvent, broadcast } from 'on-ngx-event-bus';

export class MyEvent extends GEvent {
static readonly TYPE = MyEventTypes.MyEvent;

constructor(payload: MyEventPayload) {
super(MyEvent.TYPE, payload);
}
}

broadcast(
new MyEvent({
metadata: "Fully typed and refactor-safe!"
})
);
```
- ✅ Fully typed — TypeScript strictly enforces both event type and payload, guaranteeing their correct relationship.
- ✅ Refactor-safe — renaming the event or payload interface will automatically propagate errors if used incorrectly.
- ✅ Best developer experience — IDE autocompletion, type-checking, and maintainability are maximized.
- ✅ Large-app ready — ideal for apps with many events and complex interactions.

## Final Thoughts ✨

`ngx-event-bus` is designed to scale with your application — from small components to large, event-rich Angular systems.

It removes boilerplate, enforces correctness at compile time, and lets you focus on **intent**, not wiring.
If your app relies on clean, decoupled communication, this library is built for you.

## Help / Support 💬

If you run into any issues or have questions about using **ngx-event-bus**, feel free to reach out.

📧 Email: [natenorel@gmail.com](mailto:natenorel@gmail.com)

🐞 **Bug reports & feature requests:**
Please [open an issue on GitHub](https://github.com/orelnatan/ngx-event-bus-lib/issues)