forked from fabric8-ui/fabric8-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
related to openshiftio/openshift.io#2629 related to openshiftio/openshift.io#2529
- Loading branch information
1 parent
8f49345
commit ac111f1
Showing
6 changed files
with
167 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { | ||
Inject, | ||
Injectable, | ||
InjectionToken | ||
} from '@angular/core'; | ||
|
||
import { | ||
Observable, | ||
Observer | ||
} from 'rxjs'; | ||
|
||
import { | ||
Event, | ||
EventBus | ||
} from './event-bus.service'; | ||
|
||
// EVENTS_LISTENER *must* also be used with "multi" attribute set to true | ||
export const EVENTS_LISTENER: InjectionToken<string> = new InjectionToken<string>('EventsListener'); | ||
|
||
export abstract class EventsListener<Event> implements Observer<Event> { | ||
eventTypes: string[]; | ||
abstract next(event: Event); | ||
error(err: any): void { } | ||
complete(): void { } | ||
} | ||
|
||
@Injectable() | ||
export class EventBusRegistry { | ||
constructor( | ||
private readonly eventBus: EventBus, | ||
// Force DI to initialize all listeners in hierarchy | ||
@Inject(EVENTS_LISTENER) private readonly listeners: EventsListener<Event<any>>[] | ||
) { | ||
listeners.forEach((listener: EventsListener<Event<any>>): void => { | ||
let obs: Observable<any>; | ||
if (listener.eventTypes.length > 0) { | ||
obs = eventBus.for(listener.eventTypes[0], ...listener.eventTypes.slice(1)); | ||
} else { | ||
obs = eventBus.for(listener.eventTypes[0]); | ||
} | ||
obs.subscribe(listener); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { NgModule } from '@angular/core'; | ||
|
||
import { Observable } from 'rxjs'; | ||
|
||
import { | ||
EventBusRegistry, | ||
EVENTS_LISTENER, | ||
EventsListener | ||
} from './event-bus-registry'; | ||
import { | ||
Event, | ||
EventBus, | ||
EVENTS_PROVIDER, | ||
EventsProvider, | ||
EventType | ||
} from './event-bus.service'; | ||
|
||
@NgModule({ | ||
imports: [], | ||
providers: [ | ||
EventBus, | ||
EventBusRegistry, | ||
// stub default EVENTS_PROVIDER and EVENTS_LISTENER so DI doesn't choke if | ||
// no other modules provide custom providers and listeners | ||
{ | ||
provide: EVENTS_PROVIDER, | ||
useValue: ({ | ||
eventType: EventType.GENERIC, | ||
events: Observable.never() | ||
} as EventsProvider<void>), | ||
multi: true | ||
}, | ||
{ | ||
provide: EVENTS_LISTENER, | ||
useValue: ({ | ||
eventTypes: [], | ||
next: () => null, | ||
error: () => null, | ||
complete: () => null | ||
} as EventsListener<void>), | ||
multi: true | ||
} | ||
] | ||
}) | ||
export class EventBusModule { } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { | ||
Inject, | ||
Injectable, | ||
InjectionToken | ||
} from '@angular/core'; | ||
|
||
import { | ||
Observable, | ||
Subject | ||
} from 'rxjs'; | ||
|
||
import { includes } from 'lodash'; | ||
|
||
// Per-module EventsProvider implementations *MUST* set the "multi" attribute to true | ||
export const EVENTS_PROVIDER: InjectionToken<string> = new InjectionToken<string>('EventsProvider'); | ||
|
||
export interface EventsProvider<T> { | ||
eventType: string; | ||
events: Observable<T>; | ||
} | ||
|
||
// Common event types for all publishers and subscribers. | ||
// Publishers and subscribers are also free to use plain strings | ||
// as event types to tag their own events so that this enum does | ||
// not need to be updated to reflect every single use case. | ||
export enum EventType { | ||
GENERIC = 'Generic' | ||
} | ||
|
||
export interface Event<T> { | ||
type: string; | ||
message: T; | ||
} | ||
|
||
@Injectable() | ||
export class EventBus { | ||
|
||
private readonly stream: Subject<Event<any>> = new Subject<Event<any>>(); | ||
|
||
constructor( | ||
@Inject(EVENTS_PROVIDER) private readonly eventsProviders: EventsProvider<any>[] | ||
) { | ||
eventsProviders.forEach((eventsProvider: EventsProvider<any>): void => this.register(eventsProvider)); | ||
} | ||
|
||
private register(eventsProvider: EventsProvider<any>): void { | ||
if (eventsProvider.eventType == null) { | ||
console.error('Received EventsProvider without EventType!'); | ||
return; | ||
} | ||
if (!eventsProvider.events) { | ||
console.error('Received EventsProvider without events!'); | ||
return; | ||
} | ||
eventsProvider.events | ||
.map((e: any): Event<any> => ({ type: eventsProvider.eventType, message: e })) | ||
.subscribe((event: any): void => this.stream.next(event)); | ||
} | ||
|
||
all(): Observable<Event<any>> { | ||
return this.stream.asObservable(); | ||
} | ||
|
||
for(eventType: string, ...eventTypes: string[]): Observable<Event<any>> { | ||
return this.all() | ||
.filter((event: Event<any>): boolean => includes([eventType, ...eventTypes], event.type)); | ||
} | ||
|
||
} |