Skip to content

Commit 2a37b61

Browse files
feat: observable pattern
1 parent d8d52f2 commit 2a37b61

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

src/observables/index.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Subject, Observer } from './subject';
2+
import { EventData, EventType } from '../actions/types';
3+
4+
const NAMESPACE = '__nmrium_events__';
5+
6+
function initSubject(event: EventType) {
7+
if (!window?.[NAMESPACE]?.[event]) {
8+
window[NAMESPACE] = {
9+
...window[NAMESPACE],
10+
[event]: new Subject(),
11+
};
12+
}
13+
}
14+
15+
function trigger<T extends EventType>(event: T, data: EventData<T>) {
16+
initSubject(event);
17+
window[NAMESPACE][event].notify(data);
18+
}
19+
20+
function unsubscribe(event: EventType, observerID: string) {
21+
return () => {
22+
if (window?.[NAMESPACE]?.[event]) {
23+
window[NAMESPACE][event].unsubscribe(observerID);
24+
} else {
25+
throw new Error('No event Registered');
26+
}
27+
};
28+
}
29+
30+
function subscribe<T extends EventType>(
31+
event: T,
32+
onData: (data: EventData<T>) => void,
33+
) {
34+
initSubject(event);
35+
const id = Math.random().toString(36).slice(2, 9);
36+
37+
const observer: Observer = { id, update: onData } as Observer;
38+
39+
(window[NAMESPACE][event] as Subject).subscribe(observer);
40+
41+
return unsubscribe(event, id);
42+
}
43+
44+
export default { trigger, subscribe };

src/observables/subject.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export interface Observer {
2+
readonly id: string;
3+
update: (data: unknown) => void;
4+
}
5+
6+
export class Subject {
7+
private observers: Observer[] = [];
8+
9+
subscribe(observer: Observer) {
10+
this.observers.push(observer);
11+
}
12+
13+
unsubscribe(observerID: string) {
14+
this.observers = this.observers.filter((_observer) => {
15+
return _observer.id !== observerID;
16+
});
17+
}
18+
19+
notify(data: unknown) {
20+
this.observers.forEach((observer) => {
21+
observer.update(data);
22+
});
23+
}
24+
}

0 commit comments

Comments
 (0)