An in-memory typed publish and subscribe event bus. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
npm install @pamoja/bus
This pulls in @pamoja/native, the compiled engine. npm install pamoja is the whole framework in one package.
The test that runs in CI, spliced here as it ran.
From bindings/node/guides/bus.ts:
import { EventBus } from '@pamoja/bus'
async function main() {
// A sampler announces something and whatever cares picks it up, with neither side
// holding a reference to the other. This is how the parts of one node are wired.
const hub = new EventBus(8)
const control = await hub.subscribe()
const logger = await hub.subscribe()
await hub.publish(Buffer.from('battery.low'))
const toControl = (await control.next())!
const toLogger = (await logger.next())!
console.log(`control saw ${toControl.toString()}, the logger saw ${toLogger.toString()}`)
// A subscriber taken later starts from the next event, so it never sees what went out
// before it existed.
const late = await hub.subscribe()
await hub.publish(Buffer.from('link.up'))
const firstSeen = (await late.next())!
console.log(`the late subscriber's first event is ${firstSeen.toString()}`)
// The buffer is per subscriber and bounded, so one further behind than the capacity
// drops what it missed and resumes with the most recent events. A slow reader costs
// itself, not the publisher.
const slow = new EventBus(2)
const reader = await slow.subscribe()
for (let count = 0; count < 5; count += 1) {
await slow.publish(Buffer.from([count]))
}
const resumed = (await reader.next())!
console.log(`after five events into a buffer of two, the reader resumes at ${resumed[0]}`)
return { toControl, toLogger, firstSeen, resumed }
}
main()
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-bus |
reference, docs.rs, install |
| TypeScript | @pamoja/bus |
reference, install |
| Python | pamoja-bus |
reference, install |
| C# | Pamoja.Bus |
reference, install |
@pamoja/bus reference, every class, function, and type this package exports.MIT
Ergonomic facade over the generated event-bus binding.
One publisher, many subscribers, inside a single process. It is how the parts of a gateway talk to each other without knowing about each other, so a sampler can announce a reading and whatever cares about readings picks it up.
A subscriber only sees events published after it existed, so subscribe before publishing anything it needs to see.