a post-component library for building user-interfaces on the web.
1export class Bus<Event extends string> {
2 #listeners: { [E in Event]?: Set<() => void> } = {}
3 #channel: BroadcastChannel
4
5 constructor(name: string) {
6 this.#channel = new BroadcastChannel(name)
7 }
8
9 emit(...events: Event[]) {
10 for (const event of events) {
11 this.#channel.postMessage(event)
12
13 const listeners = this.#listeners[event]
14 if (listeners) for (const listener of listeners) listener()
15 }
16 }
17
18 subscribe(event: Event, listener: () => void) {
19 const listeners = (this.#listeners[event] ??= new Set())
20 listeners.add(listener)
21
22 const handler = ({ data }: { data: string }) => {
23 if (data === event) listener()
24 }
25 this.#channel.addEventListener('message', handler)
26 return () => {
27 listeners.delete(listener)
28 this.#channel.removeEventListener('message', handler)
29 }
30 }
31
32 close() {
33 this.#channel.close()
34 }
35}