v5.7.1
Adding a new helper class: Bus
Commit 3733bf6
Throughout Earthstar we use the Emitter
class to subscribe to and send events. I've added a similar class, Bus
, which lets you separate your events into channels.
This way if you have several kinds of events you don't need to make several Emitter instances, you can just use one Bus.
// define your channel names and their types
interface Channels {
click: string,
drag: number,
}
let bus = new Bus<Channels>();
bus.subscribe("click", (msg) => { console.log("click happened", msg) });
bus.subscribe("drag", (msg) => { console.log("drag happened", msg) });
bus.send("click", "this is the click message");
bus.send("drag", 12345);
// send() returns after the callbacks are done running.
It can also handle async functions:
bus.subscribe("click", async (msg) => {
console.log("click happened", msg);
await sleep(1000);
});
await bus.send("click", "hello");
// await send() will block until the callbacks are all done, even the async callbacks
I expect this will be useful when building Layers that you can subscribe to. Imagine something like this:
// imaginary code
let todoLayer = new TodoLayer(myStorage);
todoLayer.bus.subscribe("todo:new"), (todo) => { ...... });
// Each Todo could have its own channel named after its id
todoLayer.bus.subscribe("todo:update:1833298"), (todo) => { ...... });
Bus
scales efficiently to thousands of channels and can handle frequent re-subscriptions quickly, so it can be used from React to subscribe to each Todo separately.
This might also be used in IStorage
, like:
// imaginary code
// subscribe to a single document
myStorage.bus.subscribe("doc:update:/about/foo/bar.txt", (doc) => { ...... });
Lastly, you can subscribe to all channels using "*"
but read the comments below for details.
There are extensive comments in the code describing how it works in more detail.
Code: https://github.com/earthstar-project/earthstar/blob/master/src/util/emitter.ts
Tests: https://github.com/earthstar-project/earthstar/blob/master/src/test/emitter.test.ts