blob: c4b109f1d575a6dc50034daf4ac5505949250dab [file] [log] [blame]
Idan Amit71904f22018-02-13 10:38:16 +02001declare const window: Window;
2
3export class BasePubSub {
4
5 subscribers: Map<string, ISubscriber>;
6 eventsCallbacks: Array<Function>;
7 clientId: string;
Idan Amit6187c942018-04-15 19:19:08 +03008 eventsToWait: Map<string, Array<string>>;
Idan Amit71904f22018-02-13 10:38:16 +02009
10 constructor(pluginId: string) {
11 this.subscribers = new Map<string, ISubscriber>();
Idan Amit6187c942018-04-15 19:19:08 +030012 this.eventsCallbacks = [];
13 this.eventsToWait = new Map<string, Array<string>>();
Idan Amit71904f22018-02-13 10:38:16 +020014 this.clientId = pluginId;
15 this.onMessage = this.onMessage.bind(this);
16
17 window.addEventListener("message", this.onMessage);
18 }
19
20 public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) {
21 const subscriber = {
22 window: subscriberWindow,
23 locationUrl: subscriberUrl || subscriberWindow.location.href
24 } as ISubscriber;
25
26 this.subscribers.set(subscriberId, subscriber);
27 }
28
29 public unregister(subscriberId: string) {
30 this.subscribers.delete(subscriberId);
31 }
32
33 public on(callback: Function) {
Idan Amit6187c942018-04-15 19:19:08 +030034 let functionExists = this.eventsCallbacks.find((func: Function) => {
35 return callback.toString() == func.toString()
36 });
37
38 if (!functionExists) {
39 this.eventsCallbacks.push(callback);
40 }
Idan Amit71904f22018-02-13 10:38:16 +020041 }
42
43 public off(callback: Function) {
44 let index = this.eventsCallbacks.indexOf(callback);
45 this.eventsCallbacks.splice(index, 1)
46 }
47
Idan Amitf97bae32018-03-06 13:52:58 +020048 public notify(eventType:string, eventData?:any) {
Idan Amit71904f22018-02-13 10:38:16 +020049 let eventObj = {
50 type: eventType,
51 data: eventData,
52 originId: this.clientId
53 } as IPubSubEvent;
54
Idan Amit6187c942018-04-15 19:19:08 +030055 this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => {
56 subscriber.window.postMessage(eventObj, subscriber.locationUrl);
57
Idan Amit71904f22018-02-13 10:38:16 +020058 });
Idan Amit6187c942018-04-15 19:19:08 +030059
60 return {
61 subscribe: function(callbackFn) {
62
63 if(this.subscribers.size !== 0) {
64 let subscribersToNotify = Array.from(this.subscribers.keys());
65
66 const checkNotifyComplete = (subscriberId: string) => {
67
68 let index = subscribersToNotify.indexOf(subscriberId);
69 subscribersToNotify.splice(index, 1);
70
71 if (subscribersToNotify.length === 0) {
72 callbackFn();
73 }
74 };
75
76 this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => {
77 if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) {
78
79 const actionCompletedFunction = (eventData, subId = subscriberId) => {
80 if (eventData.type == "ACTION_COMPLETED") {
81 checkNotifyComplete(subId);
82 }
83 this.off(actionCompletedFunction);
84
85 };
86 this.on(actionCompletedFunction);
87 }
88 else {
89 checkNotifyComplete(subscriberId);
90 }
91 });
92 }
93 else {
94 callbackFn();
95 }
96 }.bind(this)
97 }
Idan Amit71904f22018-02-13 10:38:16 +020098 }
99
Idan Amitecd3d712018-05-07 15:55:00 +0300100 public isWaitingForEvent(eventName: string) : boolean {
101 return Array.from(this.eventsToWait.values()).some((eventsList: Array<string>) =>
102 eventsList.indexOf(eventName) !== -1
103 );
104 }
105
Idan Amit71904f22018-02-13 10:38:16 +0200106 protected onMessage(event: any) {
107 if (this.subscribers.has(event.data.originId)) {
108 this.eventsCallbacks.forEach((callback: Function) => {
109 callback(event.data, event);
110 })
111 }
112 }
113}
114
Idan Amit71904f22018-02-13 10:38:16 +0200115export interface IPubSubEvent {
116 type: string;
117 originId: string;
118 data: any;
119}
120
121export interface ISubscriber {
122 window: Window;
123 locationUrl: string;
124}