blob: 41e8039da5e8df0a0d4a7e0d018e94ef563f61e7 [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 Amit60c47df2018-05-08 16:06:34 +03009 lastEventNotified: string;
Idan Amit71904f22018-02-13 10:38:16 +020010
11 constructor(pluginId: string) {
12 this.subscribers = new Map<string, ISubscriber>();
Idan Amit6187c942018-04-15 19:19:08 +030013 this.eventsCallbacks = [];
14 this.eventsToWait = new Map<string, Array<string>>();
Idan Amit71904f22018-02-13 10:38:16 +020015 this.clientId = pluginId;
Idan Amit60c47df2018-05-08 16:06:34 +030016 this.lastEventNotified = "";
Idan Amit71904f22018-02-13 10:38:16 +020017 this.onMessage = this.onMessage.bind(this);
18
19 window.addEventListener("message", this.onMessage);
20 }
21
22 public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) {
23 const subscriber = {
24 window: subscriberWindow,
25 locationUrl: subscriberUrl || subscriberWindow.location.href
26 } as ISubscriber;
27
28 this.subscribers.set(subscriberId, subscriber);
29 }
30
31 public unregister(subscriberId: string) {
32 this.subscribers.delete(subscriberId);
33 }
34
35 public on(callback: Function) {
Idan Amit6187c942018-04-15 19:19:08 +030036 let functionExists = this.eventsCallbacks.find((func: Function) => {
37 return callback.toString() == func.toString()
38 });
39
40 if (!functionExists) {
41 this.eventsCallbacks.push(callback);
42 }
Idan Amit71904f22018-02-13 10:38:16 +020043 }
44
45 public off(callback: Function) {
46 let index = this.eventsCallbacks.indexOf(callback);
47 this.eventsCallbacks.splice(index, 1)
48 }
49
Idan Amitf97bae32018-03-06 13:52:58 +020050 public notify(eventType:string, eventData?:any) {
Idan Amit71904f22018-02-13 10:38:16 +020051 let eventObj = {
52 type: eventType,
53 data: eventData,
54 originId: this.clientId
55 } as IPubSubEvent;
56
Idan Amit6187c942018-04-15 19:19:08 +030057 this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => {
58 subscriber.window.postMessage(eventObj, subscriber.locationUrl);
Idan Amit71904f22018-02-13 10:38:16 +020059 });
Idan Amit6187c942018-04-15 19:19:08 +030060
Idan Amit60c47df2018-05-08 16:06:34 +030061 this.lastEventNotified = eventType;
62
Idan Amit6187c942018-04-15 19:19:08 +030063 return {
64 subscribe: function(callbackFn) {
65
66 if(this.subscribers.size !== 0) {
67 let subscribersToNotify = Array.from(this.subscribers.keys());
68
69 const checkNotifyComplete = (subscriberId: string) => {
70
71 let index = subscribersToNotify.indexOf(subscriberId);
72 subscribersToNotify.splice(index, 1);
73
74 if (subscribersToNotify.length === 0) {
75 callbackFn();
76 }
77 };
78
79 this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => {
80 if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) {
81
82 const actionCompletedFunction = (eventData, subId = subscriberId) => {
83 if (eventData.type == "ACTION_COMPLETED") {
84 checkNotifyComplete(subId);
85 }
86 this.off(actionCompletedFunction);
87
88 };
89 this.on(actionCompletedFunction);
90 }
91 else {
92 checkNotifyComplete(subscriberId);
93 }
94 });
95 }
96 else {
97 callbackFn();
98 }
99 }.bind(this)
100 }
Idan Amit71904f22018-02-13 10:38:16 +0200101 }
102
Idan Amitecd3d712018-05-07 15:55:00 +0300103 public isWaitingForEvent(eventName: string) : boolean {
104 return Array.from(this.eventsToWait.values()).some((eventsList: Array<string>) =>
105 eventsList.indexOf(eventName) !== -1
106 );
107 }
108
Idan Amit71904f22018-02-13 10:38:16 +0200109 protected onMessage(event: any) {
110 if (this.subscribers.has(event.data.originId)) {
111 this.eventsCallbacks.forEach((callback: Function) => {
112 callback(event.data, event);
113 })
114 }
115 }
116}
117
Idan Amit71904f22018-02-13 10:38:16 +0200118export interface IPubSubEvent {
119 type: string;
120 originId: string;
121 data: any;
122}
123
124export interface ISubscriber {
125 window: Window;
126 locationUrl: string;
127}