Overview
The EventBus is a simple pub/sub system that enables decoupled communication between plugins.
api.bus.on('todo:added', (data) => {
console.log('New todo:', data.text);
});
api.bus.emit('todo:added', { text: 'Buy milk' });
Methods
bus.on(event, callback)
Subscribe to an event. Multiple listeners can subscribe to the same event.
api.bus.on('theme:changed', (data) => {
document.body.style.background = data.color;
});
| Parameter | Type | Description |
|---|
event | string | Event name |
callback | function | Handler called with event data |
bus.off(event, callback)
Unsubscribe from an event. Must pass the same function reference used in on().
function handler(data) { /* ... */ }
api.bus.on('my-event', handler);
// later:
api.bus.off('my-event', handler);
bus.once(event, callback)
Subscribe to an event, but the listener is automatically removed after the first emission.
api.bus.once('board:ready', (data) => {
console.log('Board is ready, only fires once');
});
| Parameter | Type | Description |
|---|
event | string | Event name |
callback | function | Handler called once with event data, then removed |
bus.emit(event, data)
Publish an event to all subscribers. Errors in listeners are caught and logged without interrupting other listeners.
api.bus.emit('todo:added', { text: 'Buy milk', done: false });
| Parameter | Type | Description |
|---|
event | string | Event name |
data | any | Payload passed to subscribers |
bus.removeAll([event])
Remove all listeners for a specific event, or all events if no event name is given.
// Remove all listeners for a specific event
api.bus.removeAll('todo:added');
// Remove ALL listeners across all events
api.bus.removeAll();
| Parameter | Type | Description |
|---|
event | string | (Optional) Event name. If omitted, clears everything. |
removeAll() with no arguments is a nuclear option. Use with care — it removes listeners from every plugin, not just yours.
Naming Convention
Use namespace:action to avoid collisions between plugins:
| ✅ Good | ❌ Bad |
|---|
todo:added | added |
kanban:card:moved | move |
theme:changed | change |
sticky-note:created | new |
Example: Cross-Plugin Communication
// === todo-list/plugin.js ===
export function setup(api) {
const todos = [];
function addTodo(text) {
todos.push({ text, done: false });
api.bus.emit('todo:added', { text, count: todos.length });
}
}
// === stats/plugin.js ===
export function setup(api) {
let count = 0;
api.bus.on('todo:added', (data) => {
count = data.count;
renderStats();
});
}
Plugins should never directly import or reference each other. Always use the event bus for communication.