51 lines
925 B
TypeScript
51 lines
925 B
TypeScript
|
type Listener = (value: any) => void;
|
||
|
|
||
|
type Topics = {
|
||
|
[name: string]: Listener[];
|
||
|
};
|
||
|
|
||
|
export const createPubSub = () => {
|
||
|
let topics: Topics = {};
|
||
|
let destroyed = false;
|
||
|
|
||
|
const getTopic = (name: string) => {
|
||
|
if (!topics[name]) {
|
||
|
topics[name] = [];
|
||
|
}
|
||
|
|
||
|
return topics[name];
|
||
|
};
|
||
|
|
||
|
return {
|
||
|
subscribe(topic: string, fn: Listener) {
|
||
|
const listeners = getTopic(topic);
|
||
|
|
||
|
listeners.push(fn);
|
||
|
|
||
|
const unsubscribe = () => {
|
||
|
const index = listeners.indexOf(fn);
|
||
|
|
||
|
listeners.splice(index, 1);
|
||
|
};
|
||
|
|
||
|
return unsubscribe;
|
||
|
},
|
||
|
|
||
|
publish(topic: string, value: any) {
|
||
|
const listeners = getTopic(topic);
|
||
|
const currentListeners = listeners.slice();
|
||
|
|
||
|
currentListeners.forEach((listener) => {
|
||
|
if (!destroyed) {
|
||
|
listener(value);
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
destroy() {
|
||
|
topics = {};
|
||
|
destroyed = true;
|
||
|
},
|
||
|
};
|
||
|
};
|