-
-
Notifications
You must be signed in to change notification settings - Fork 310
/
plugin-event.service.ts
87 lines (74 loc) · 2.18 KB
/
plugin-event.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Based on: https://github.com/bennadel/JavaScript-Demos/blob/master/demos/message-bus-actions-angular6/app/message-bus.ts
import { Injectable, ErrorHandler } from '@angular/core';
import { PluginEvent, PluginEventCallback, PluginEventPayloadMap } from 'altair-graphql-core/build/plugin/event/event.interfaces';
import { Subject, Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
interface PluginEventData {
event: PluginEvent;
payload: any;
}
@Injectable({
providedIn: 'root'
})
export class PluginEventService {
private eventStream = new Subject<PluginEventData>();
constructor(
private errorHandler: ErrorHandler,
) {}
/**
* Creates a group for managing multiple subscriptions within single contexts
*/
group() {
return new PluginEventGroup(this);
}
/**
* Pushes an event data to the stream
*/
emit<E extends PluginEvent>(event: E, payload: PluginEventPayloadMap[E]) {
return this.eventStream.next({
event,
payload,
});
}
/**
* Subscribe to specific event
*/
on<E extends PluginEvent>(event: E, callback: PluginEventCallback<E>) {
return this.eventStream.pipe(
filter(_ => _.event === event),
).subscribe(evtData => {
try {
callback(evtData.payload);
} catch (error) {
this.errorHandler.handleError(error);
}
});
}
}
class PluginEventGroup {
private subscriptions: Subscription[] = [];
constructor(
private pluginEventService: PluginEventService,
) {}
emit<E extends PluginEvent>(event: E, payload: PluginEventPayloadMap[E]) {
return this.pluginEventService.emit(event, payload);
}
on<E extends PluginEvent>(event: E, callback: PluginEventCallback<E>) {
const subscription = this.pluginEventService.on(event, callback);
this.subscriptions.push(subscription);
return {
unsubscribe: () => {
this.subscriptions = this.subscriptions.filter(_ => _ !== subscription);
if (!subscription.closed) {
return subscription.unsubscribe();
}
},
};
}
unsubscribe() {
for (const subscription of this.subscriptions) {
subscription.unsubscribe();
}
this.subscriptions = [];
}
}