Bus Class
A type-safe event bus for cross-component communication. Built on EventTarget, it enforces event types at compile time and supports automatic cleanup via AbortSignal.
Import
typescript
import { Bus } from '@jadis/core';Creating a Bus
typescript
type AppEvents = {
userLoggedIn: { id: string; name: string };
themeChanged: 'light' | 'dark';
notification: string;
};
const appBus = new Bus<AppEvents>();Methods
register(event, callback, signal)
Registers a listener for a specific event. Outside a Jadis component, provide an AbortSignal for cleanup.
typescript
const controller = new AbortController();
appBus.register('userLoggedIn', (detail) => {
console.log(`User ${detail.name} logged in`);
}, controller.signal);Inside Jadis components, prefer this.onBus(bus, event, callback) instead.
emit(event, detail?)
Dispatches an event with optional detail:
typescript
appBus.emit('userLoggedIn', { id: 'abc123', name: 'Alice' });
appBus.emit('themeChanged', 'dark');
appBus.emit('notification', 'New message received');Full example
tsx
import { Bus, Jadis } from '@jadis/core';
type AppEvents = {
dataLoaded: string[];
error: Error;
};
const bus = new Bus<AppEvents>();
const fetchData = async (): Promise<string[]> => ['ready'];
class LogPanel extends Jadis {
static readonly selector = 'log-panel';
onConnect(): void {
this.onBus(bus, 'dataLoaded', (items) => {
console.log(`Loaded ${items.length} items`);
});
this.onBus(bus, 'error', (error) => {
console.error('Error:', error.message);
});
}
templateHtml(): Node {
return <div>Log Panel</div>;
}
}
class DataFetcher extends Jadis {
static readonly selector = 'data-fetcher';
onConnect(): void {
fetchData()
.then((items) => bus.emit('dataLoaded', items))
.catch((error) => bus.emit('error', error));
}
templateHtml(): Node {
return <div>Data Fetcher</div>;
}
}
LogPanel.register();
DataFetcher.register();Outside Jadis components
Manage the AbortController manually:
typescript
const controller = new AbortController();
bus.register('dataLoaded', (items) => console.log(items), controller.signal);
controller.abort();