# core/buses/base.bus.ts

> 27 lines of code and 6 definitions.

Tree: Site tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/tree#file-core-buses-base-bus-ts
Source text: https://banes-lab.com/assets/sources/source.f9dd2f9dc2a4ff022afe711b0a5a8fb29bc5cfdededfd75205b5b444022a631c.generated.txt

## Definitions

- `emitEvent` (lexical_declaration, line 27, exported)
- `isNamed` (lexical_declaration, line 6)
- `subscribeEvent` (lexical_declaration, line 10, exported)
- `guarded` (lexical_declaration, line 15, exported)
- `listeners` (lexical_declaration, line 4)
- `existing` (lexical_declaration, line 14, exported)

## Used by

- [presentation/components/link.component.ts](https://banes-lab.com/source/tree/presentation/components/link.component.ts.md)
- [presentation/components/menu.component.ts](https://banes-lab.com/source/tree/presentation/components/menu.component.ts.md)
- [presentation/components/overlay.component.ts](https://banes-lab.com/source/tree/presentation/components/overlay.component.ts.md)
- [presentation/components/search.component.ts](https://banes-lab.com/source/tree/presentation/components/search.component.ts.md)
- [presentation/components/tab.component.ts](https://banes-lab.com/source/tree/presentation/components/tab.component.ts.md)
- [presentation/widgets/home.widget.ts](https://banes-lab.com/source/tree/presentation/widgets/home.widget.ts.md)
- [presentation/widgets/overlay.widget.ts](https://banes-lab.com/source/tree/presentation/widgets/overlay.widget.ts.md)
- [presentation/widgets/tab.widget.ts](https://banes-lab.com/source/tree/presentation/widgets/tab.widget.ts.md)
- [runtime/coordinators/route.coordinator.ts](https://banes-lab.com/source/tree/runtime/coordinators/route.coordinator.ts.md)

## Source

```typescript
import type { AppEvent, EventListener, EventName, EventOf } from "#types/event.types";
import type { Disposer } from "#types/base.types";

const listeners = new Map<EventName, Set<EventListener>>();

const isNamed = function isNamed<N extends EventName>(event: AppEvent, name: N): event is EventOf<N> {
    return event.name === name;
};

export const subscribeEvent = function subscribeEvent<N extends EventName>(
    name: N,
    listener: EventListener<EventOf<N>>,
): Disposer {
    const existing = listeners.get(name) ?? new Set<EventListener>();
    const guarded: EventListener = (event) => {
        if (isNamed(event, name)) {
            listener(event);
        }
    };
    existing.add(guarded);
    listeners.set(name, existing);
    return () => {
        existing.delete(guarded);
    };
};

export const emitEvent = function emitEvent(event: AppEvent): void {
    for (const listener of listeners.get(event.name) ?? []) {
        listener(event);
    }
};
```
