From a2c544de543343ad4135f0419f1548ed1cf502cb Mon Sep 17 00:00:00 2001 From: Idan Amit Date: Thu, 19 Jul 2018 12:05:50 +0300 Subject: sdc-pubsub first commit Committed sdc-pubsub code for the first time to LF repo Change-Id: I1e26f7fe8b2f1747169e3101e0705d1c89d3f56b Issue-ID: SDC-1537 Signed-off-by: Idan Amit --- lib/base-pubsub.ts | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 lib/base-pubsub.ts (limited to 'lib/base-pubsub.ts') diff --git a/lib/base-pubsub.ts b/lib/base-pubsub.ts new file mode 100644 index 0000000..41e8039 --- /dev/null +++ b/lib/base-pubsub.ts @@ -0,0 +1,127 @@ +declare const window: Window; + +export class BasePubSub { + + subscribers: Map; + eventsCallbacks: Array; + clientId: string; + eventsToWait: Map>; + lastEventNotified: string; + + constructor(pluginId: string) { + this.subscribers = new Map(); + this.eventsCallbacks = []; + this.eventsToWait = new Map>(); + this.clientId = pluginId; + this.lastEventNotified = ""; + this.onMessage = this.onMessage.bind(this); + + window.addEventListener("message", this.onMessage); + } + + public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) { + const subscriber = { + window: subscriberWindow, + locationUrl: subscriberUrl || subscriberWindow.location.href + } as ISubscriber; + + this.subscribers.set(subscriberId, subscriber); + } + + public unregister(subscriberId: string) { + this.subscribers.delete(subscriberId); + } + + public on(callback: Function) { + let functionExists = this.eventsCallbacks.find((func: Function) => { + return callback.toString() == func.toString() + }); + + if (!functionExists) { + this.eventsCallbacks.push(callback); + } + } + + public off(callback: Function) { + let index = this.eventsCallbacks.indexOf(callback); + this.eventsCallbacks.splice(index, 1) + } + + public notify(eventType:string, eventData?:any) { + let eventObj = { + type: eventType, + data: eventData, + originId: this.clientId + } as IPubSubEvent; + + this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => { + subscriber.window.postMessage(eventObj, subscriber.locationUrl); + }); + + this.lastEventNotified = eventType; + + return { + subscribe: function(callbackFn) { + + if(this.subscribers.size !== 0) { + let subscribersToNotify = Array.from(this.subscribers.keys()); + + const checkNotifyComplete = (subscriberId: string) => { + + let index = subscribersToNotify.indexOf(subscriberId); + subscribersToNotify.splice(index, 1); + + if (subscribersToNotify.length === 0) { + callbackFn(); + } + }; + + this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => { + if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) { + + const actionCompletedFunction = (eventData, subId = subscriberId) => { + if (eventData.type == "ACTION_COMPLETED") { + checkNotifyComplete(subId); + } + this.off(actionCompletedFunction); + + }; + this.on(actionCompletedFunction); + } + else { + checkNotifyComplete(subscriberId); + } + }); + } + else { + callbackFn(); + } + }.bind(this) + } + } + + public isWaitingForEvent(eventName: string) : boolean { + return Array.from(this.eventsToWait.values()).some((eventsList: Array) => + eventsList.indexOf(eventName) !== -1 + ); + } + + protected onMessage(event: any) { + if (this.subscribers.has(event.data.originId)) { + this.eventsCallbacks.forEach((callback: Function) => { + callback(event.data, event); + }) + } + } +} + +export interface IPubSubEvent { + type: string; + originId: string; + data: any; +} + +export interface ISubscriber { + window: Window; + locationUrl: string; +} -- cgit 1.2.3-korg