An in-process transport with topic matching and a fault injector, for testing with no broker. One capability of pamoja, one memory-safe Rust core with bindings for TypeScript, Python, and C#.
npm install @pamoja/loopback
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/loopback.ts:
import { LoopbackBroker } from '@pamoja/loopback'
async function main() {
// One broker and two links off it, all in this process. Nothing binds a port and nothing
// has to be running for the traffic below to flow, which is what makes this the link to
// develop a node against before it has a real one.
const broker = new LoopbackBroker()
const publisher = broker.link()
const subscriber = broker.link()
await publisher.connect()
await subscriber.connect()
// A `+` stands for exactly one level, so this takes the mixer's temperature but not the
// raw reading a level below it.
await subscriber.subscribe('line/+/temp')
await publisher.send('line/mixer/temp/raw', Buffer.from('2150'))
await publisher.send('line/mixer/temp', Buffer.from('21.5'))
const message = (await subscriber.recv())!
console.log(`line/+/temp took ${message.payload.toString()} from ${message.topic}`)
// A `#` covers every level that remains, so a second link takes the whole subtree,
// including the reading the single-level filter passed over.
const watcher = broker.link()
await watcher.connect()
await watcher.subscribe('line/#')
await publisher.send('line/mixer/temp/raw', Buffer.from('2150'))
const deep = (await watcher.recv())!
console.log(`line/# took ${deep.payload.toString()} from ${deep.topic}`)
// A link that has been disconnected reports the failure instead of dropping the reading,
// which is the case a test wants to reach without unplugging anything.
await publisher.disconnect()
try {
await publisher.send('line/mixer/temp', Buffer.from('21.6'))
console.log('a disconnected link took a reading, which should never happen')
} catch (error) {
console.log(`disconnected refused the reading: ${(error as Error).message}`)
}
return { message, deep }
}
main()
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-loopback |
reference, docs.rs, install |
| TypeScript | @pamoja/loopback |
reference, install |
| Python | pamoja-loopback |
reference, install |
| C# | Pamoja.Loopback |
reference, install |
@pamoja/loopback reference, every class, function, and type this package exports.MIT
Ergonomic facade over the generated loopback binding.
An in-process broker: publish on one link, receive on another, with no broker process, no network, and no hardware. It is what makes a message flow testable from a unit test rather than only from a deployment.