pubsub-ts
Version:
PubSub Messaging Pattern in Typescript
134 lines (105 loc) • 3.78 kB
text/typescript
export module PubSub {
export enum NotificationType {
standard,
priority,
urgent
}
export interface Notification {
name: string;
body: any;
type: NotificationType;
}
export class Subscriber {
private standardQueue: Notification[] = [];
private priorityQueue: Notification[] = [];
private interests: Map<string, Function> = new Map();
private key: string;
private shouldPost: boolean = false;
constructor(key: string = '' + new Date().getTime()) {
this.key = key;
}
public on(eventName: string, callback: Function): void {
this.interests.set(eventName, callback);
}
public off(eventName: string): void {
this.interests.delete(eventName);
}
public getKey(): string {
return this.key;
}
public start(): void {
this.shouldPost = true;
this.processNotifications();
}
public pause(): void {
this.shouldPost = false;
}
public post(notification: Notification): void {
switch(notification.type) {
case NotificationType.standard:
this.standardQueue.unshift(notification);
break;
case NotificationType.priority:
this.priorityQueue.unshift(notification);
break;
case NotificationType.urgent:
this.postCallback(notification);
break;
}
this.processNotifications();
}
private processNotifications(): void {
if (!this.shouldPost) {
return;
}
this.postNotifications(this.priorityQueue);
this.postNotifications(this.standardQueue);
}
private postNotifications(queue: Notification[]): void {
let i = queue.length;
while (i--) {
let notification: Notification = queue[i];
this.postCallback(notification);
}
}
private postCallback(notification: Notification): void {
let callback: Function = <Function> this.interests.get(notification.name);
if (callback) {
callback.call(this, notification);
}
}
}
export class Publisher {
private subscribers: Map<string, Subscriber> = new Map();
public add(subscriber: Subscriber): void {
let key: string = subscriber.getKey();
if (!this.has(key)) {
this.subscribers.set(key, subscriber);
}
}
public delete(subscriber: Subscriber): void {
this.subscribers.delete(subscriber.getKey());
}
public has(key: string): boolean {
return this.subscribers.has(key);
}
public notify(eventName: string, data: any): void {
this.sendNotification(eventName, data, NotificationType.standard);
}
public notifyPriority(eventName: string, data: any): void {
this.sendNotification(eventName, data, NotificationType.priority);
}
public notifyUrgent(eventName: string, data: any): void {
this.sendNotification(eventName, data, NotificationType.urgent);
}
private sendNotification(eventName: string, data: any, type: NotificationType): void {
this.subscribers.forEach(subscriber => {
subscriber.post({
name: eventName,
body: data,
type: type
});
});
}
}
}