Events (revised)
danieldietrich opened this issue · comments
Candid claims to be unopinionated but ships with its own messaging solution (pub-sub). It is better to move pub-sub to its own library.
export type Topic = string;
export type Subscriptions = Set<Subscriber<any>>;
export type Subscriber<T> = (e: T) => void;
export type Unsubscribe = () => void;
export default {
publish,
subscribe
};
const topics: Map<Topic, Subscriptions> = new Map();
/**
* Subscribes a subscriber to a certain topic.
* Returns an unsubscribe function.
*/
function subscribe<T>(topic: Topic, subscriber: Subscriber<T>): Unsubscribe {
let subscriptions = topics.get(topic);
if (!subscriptions) {
topics.set(topic, subscriptions = new Set());
}
subscriptions.add(subscriber);
return () => { subscriptions!.delete(subscriber) };
}
/**
* Publishes a message to all subscribers of a given topic.
* The subscribers are informed in no particular order.
*/
function publish(topic: Topic, message: any): void {
topics.get(topic)?.forEach(subscriber => {
try {
subscriber(message);
} catch (err) {
console.error("[pubsub] error publishing message:", err, "\n", { topic, message });
}
});
}