Skip to content

Commit

Permalink
feat(ts): add TypeScript implementation of EventAggregator
Browse files Browse the repository at this point in the history
  • Loading branch information
ctoran committed Oct 16, 2015
1 parent 6618512 commit 78c9b81
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
108 changes: 108 additions & 0 deletions src/index2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import * as LogManager from 'aurelia-logging';

const logger = LogManager.getLogger('event-aggregator');

class Handler {
constructor(public messageType: any, public callback: (message: any) => void) {
this.messageType = messageType;
this.callback = callback;
}

handle(message: any) {
if (message instanceof this.messageType) {
this.callback.call(null, message);
}
}
}

export interface Subscription {
dispose(): void;
}

export class EventAggregator {
private eventLookup: any = {};
private messageHandlers: Handler[] = [];

publish<T>(event: T): void;
publish(event: string, data?: any): void;
publish(event: any, data?: any): void {
let subscribers: any[];
let i: number;

if (typeof event === 'string') {
subscribers = this.eventLookup[event];
if (subscribers) {
subscribers = subscribers.slice();
i = subscribers.length;

try {
while (i--) {
subscribers[i](data, event);
}
} catch (e) {
logger.error(e);
}
}
} else {
subscribers = this.messageHandlers.slice();
i = subscribers.length;

try {
while (i--) {
subscribers[i].handle(event);
}
} catch (e) {
logger.error(e);
}
}
}

subscribe<T>(event: Constructor<T>, callback: (message: T) => void): Subscription;
subscribe(event: string, callback: (message: any, event?: string) => void): Subscription;
subscribe(event: string|Constructor<any>, callback: (message: any, event?: string) => void): Subscription {
let handler: Function|Handler;
let subscribers: any[];

if (typeof event === 'string') {
handler = callback;
subscribers = this.eventLookup[event] || (this.eventLookup[event] = []);
} else {
handler = new Handler(event, callback);
subscribers = this.messageHandlers;
}

subscribers.push(handler);

return {
dispose() {
let idx = subscribers.indexOf(handler);
if (idx !== -1) {
subscribers.splice(idx, 1);
}
}
};
}

subscribeOnce<T>(event: Constructor<T>, callback: (message: T) => void): Subscription;
subscribeOnce(event: string, callback: (message: any, event?: string) => void): Subscription;
subscribeOnce(event: string|Constructor<any>, callback: (message: any, event?: string) => void): Subscription {
let sub = this.subscribe(<any>event, (a, b) => {
sub.dispose();
return callback(a, b);
});

return sub;
}
}

export function includeEventsIn(obj: any): EventAggregator {
let ea = new EventAggregator();
obj.subscribeOnce = (event: any, callback: any) => ea.subscribeOnce(event, callback);
obj.subscribe = (event: any, callback: any) => ea.subscribe(event, callback);
obj.publish = (event: any, data?: any) => ea.publish(event, data);
return ea;
}

export function configure(config: any): void {
config.instance(EventAggregator, includeEventsIn(config.aurelia));
}
3 changes: 3 additions & 0 deletions typings/Interfaces.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Constructor<T> {
new (...args: any[]): T;
}

0 comments on commit 78c9b81

Please sign in to comment.