https://github.com/boringnode/bus
A simple and lean service bus implementation for Node.js
https://github.com/boringnode/bus
bus framework-agnostic nodejs
Last synced: 4 days ago
JSON representation
A simple and lean service bus implementation for Node.js
- Host: GitHub
- URL: https://github.com/boringnode/bus
- Owner: boringnode
- License: mit
- Created: 2024-02-04T21:58:39.000Z (about 2 years ago)
- Default Branch: 0.x
- Last Pushed: 2026-03-01T15:00:35.000Z (13 days ago)
- Last Synced: 2026-03-01T18:18:59.999Z (13 days ago)
- Topics: bus, framework-agnostic, nodejs
- Language: TypeScript
- Homepage:
- Size: 1.88 MB
- Stars: 38
- Watchers: 3
- Forks: 5
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
[![typescript-image]][typescript-url]
[![gh-workflow-image]][gh-workflow-url]
[![npm-image]][npm-url]
[![npm-download-image]][npm-download-url]
[![license-image]][license-url]
`@boringnode/bus` is a service bus implementation for Node.js. It is designed to be simple and easy to use.
Currently, it supports the following transports:
👉 Memory: A simple in-memory transport for testing purposes.
👉 Redis: A Redis transport for production usage.
👉 Mqtt: A Mqtt transport for production usage.
## Table of Contents
- [Installation](#installation)
- [Usage](#usage)
- [Retry Queue](#retry-queue)
## Installation
```bash
npm install @boringnode/bus
```
## Usage
The module exposes a manager that can be used to register buses.
```typescript
import { BusManager } from '@boringnode/bus'
import { redis } from '@boringnode/bus/transports/redis'
import { mqtt } from '@boringnode/bus/transports/mqtt'
import { memory } from '@boringnode/bus/transports/memory'
const manager = new BusManager({
default: 'main',
transports: {
main: {
transport: memory(),
},
redis: {
transport: redis({
host: 'localhost',
port: 6379,
}),
},
mqtt: {
transport: mqtt({
host: 'localhost',
port: 1883,
}),
},
}
})
```
Once the manager is created, you can subscribe to channels and publish messages.
```typescript
manager.subscribe('channel', (message) => {
console.log('Received message', message)
})
manager.publish('channel', 'Hello world')
```
By default, the bus will use the `default` transport. You can specify different transport by using the `use` method.
```typescript
manager.use('redis').publish('channel', 'Hello world')
manager.use('mqtt').publish('channel', 'Hello world')
```
### Without the manager
If you don't need multiple buses, you can create a single bus directly by importing the transports and the Bus class.
```typescript
import { Bus } from '@boringnode/bus'
import { RedisTransport } from '@boringnode/bus/transports/redis'
const transport = new RedisTransport({
host: 'localhost',
port: 6379,
})
const bus = new Bus(transport, {
retryQueue: {
retryInterval: '100ms'
}
})
```
## Retry Queue
The bus also supports a retry queue. When a message fails to be published, it will be moved to the retry queue.
For example, your Redis server is down.
```typescript
const manager = new BusManager({
default: 'main',
transports: {
main: {
transport: redis({
host: 'localhost',
port: 6379,
}),
retryQueue: {
retryInterval: '100ms'
}
},
}
})
manager.use('redis').publish('channel', 'Hello World')
```
The message will be moved to the retry queue and will be retried every 100ms.
You have multiple options to configure the retry queue.
```typescript
export interface RetryQueueOptions {
// Enable the retry queue (default: true)
enabled?: boolean
// Defines if we allow duplicates messages in the retry queue (default: true)
removeDuplicates?: boolean
// The maximum size of the retry queue (default: null)
maxSize?: number | null
// The interval between each retry (default: false)
retryInterval?: Duration | false
}
```
## Test helpers
The module also provides some test helpers to make it easier to test the code that relies on the bus. First, you can use the `MemoryTransport` to create a bus that uses an in-memory transport.
You can also use the `ChaosTransport` to simulate a transport that fails randomly, in order to test the resilience of your code.
```ts
import { Bus } from '@boringnode/bus'
import { ChaosTransport } from '@boringnode/bus/test_helpers'
const buggyTransport = new ChaosTransport(new MemoryTransport())
const bus = new Bus(buggyTransport)
/**
* Now, every time you will try to publish a message, the transport
* will throw an error.
*/
buggyTransport.alwaysThrow()
```
[gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/boringnode/bus/checks.yml?branch=0.x&style=for-the-badge
[gh-workflow-url]: https://github.com/boringnode/bus/actions/workflows/checks.yml
[npm-image]: https://img.shields.io/npm/v/@boringnode/bus.svg?style=for-the-badge&logo=npm
[npm-url]: https://www.npmjs.com/package/@boringnode/bus
[npm-download-image]: https://img.shields.io/npm/dm/@boringnode/bus?style=for-the-badge
[npm-download-url]: https://www.npmjs.com/package/@boringnode/bus
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: https://www.typescriptlang.org
[license-image]: https://img.shields.io/npm/l/@boringnode/bus?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md