Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | 7x 7x 7x 7x 7x 7x 35x 35x 35x 35x 35x 35x | /* eslint-disable @typescript-eslint/no-explicit-any */
import { Injectable, InjectionToken, Injector, inject } from '@angular/core';
import { Observable, Subject, switchMap } from 'rxjs';
import { v4 as uuid } from 'uuid';
import { FeatureToggleService, FeatureToggleType } from 'ish-core/feature-toggle.module';
import { InjectMultiple } from 'ish-core/utils/injection';
export interface FeatureEventResultListener {
feature: string;
event: string;
resultListener$(id: string): Observable<FeatureEventResult>;
}
export interface FeatureEventResult {
id: string;
event: string;
successful: boolean;
data?: any;
}
export interface FeatureEventNotifier {
id: string;
feature: string;
event: string;
data?: any;
}
export const FEATURE_EVENT_RESULT_LISTENER = new InjectionToken<FeatureEventResultListener>(
'featureEventResultListener'
);
@Injectable({ providedIn: 'root' })
export class FeatureEventService {
private internalEventNotifier$ = new Subject<FeatureEventNotifier>();
private internalEventResult$ = new Subject<FeatureEventResult>();
private eventListeners: FeatureEventResultListener[] = [];
private featureToggleService = inject(FeatureToggleService);
/**
* Event stream to notify extensions for further actions
*/
eventNotifier$ = this.internalEventNotifier$.asObservable();
/**
* Event stream to notify for event results
*/
eventResults$ = this.internalEventResult$.asObservable();
/**
* Will send new notification to event stream. Subscriber (extensions) to this event stream could react accordingly.
* @param feature responsible extension
* @param event event type
* @param data optional data for event
* @returns identifier of generated event
*/
sendNotification(feature: string, event: string, data?: any): string {
const id = uuid();
this.internalEventNotifier$.next({ id, feature, event, data });
return id;
}
/**
* Will send results of event back. Subscriber (event trigger) to this result stream could react accordingly.
* @param id identifier of generated even
* @param event event type
* @param successful Is result successful?
* @param data optional data for event
*/
sendResult(id: string, event: string, successful: boolean, data?: any) {
this.internalEventResult$.next({ id, event, successful, data });
}
/**
* Will append all configured FEATURE_EVENT_RESULT_LISTENER together to be available in the FeatureEventNotifierService
* @param injector current injector instance
*/
setupAvailableResultListener(injector: Injector) {
// get all configured result listener by FEATURE_EVENT_RESULT_LISTENER injection token from current injector instance
const eventListeners = injector.get<InjectMultiple<typeof FEATURE_EVENT_RESULT_LISTENER>>(
FEATURE_EVENT_RESULT_LISTENER,
[]
);
// append configured listener to available eventListeners list in case it is not yet available
eventListeners.forEach(eventListener => {
Iif (this.eventListeners.find(el => el.feature === eventListener.feature && el.event === eventListener.event)) {
return;
}
this.eventListeners.push(eventListener);
});
}
/**
* Find correct event result listener
* @param feature responsible extension
* @param event event type
* @param id id of generated notification event
* @returns result listener stream, which should notify about results of notification event
*/
eventResultListener$(feature: FeatureToggleType, event: string, id: string): Observable<FeatureEventResult> {
return this.featureToggleService
.enabled$(feature)
.pipe(
switchMap(() =>
this.eventListeners.find(el => el.feature === feature && el.event === event)?.resultListener$(id)
)
);
}
}
|