import {VISUALIZER_EVENTS, PRIVATE_EVENTS} from './constants';
import {hasValue, getKey} from './utils';
/**
* Class representing a Wizart event with strict validation of event types.
* @class
* @memberof WizartDeploymentKit
*/
class WizartEvent {
/**
* Creates an instance of WizartEvent.
* @param {VisualizerEvent} eventName - The name of the event.
* @param {*} data - The event payload data.
* @throws Will throw an error if the event name is not recognized.
*/
constructor(eventName, data={}) {
if (!VISUALIZER_EVENTS.hasOwnProperty(eventName) && !hasValue(PRIVATE_EVENTS, eventName)) {
console.error(`Unknown event type ${eventName}`);
}
this.eventName = eventName;
this.data = data;
}
}
/**
* @namespace EventBus
* @memberof WizartDeploymentKit
*/
/**
* @ignore
*/
const subscribers_ = new Map();
/**
* @ignore
*/
const pushEvent = (visualizer, event) => {
if (!(event instanceof WizartEvent)) {
console.error('Event is not instance of WizartEvent class.');
}
visualizer._pushEvent(event.eventName, event.data);
}
/**
* Subscribes a callback function to an event, optionally for a specific event and/or visualizer instance.
* @function subscribe
* @memberof WizartDeploymentKit.EventBus
* @param {Function} callback - The callback function to execute when the event is triggered.
* @param {VisualizerEvent|null} eventName - Optional event name to subscribe to.
* @param {Visualizer|null} visualizer - Optional specific visualizer instance to filter events.
* @returns {symbol} A unique subscription ID for managing the subscription.
* @throws Will throw an error if callback is not a function or if visualizer is not a valid instance.
*
* @example
* const subscriptionId = WizartDeploymentKit.EventBus.subscribe((event) => {
* console.log(event);
* },
*
* // if you want to handle specific event.
* WizartDeploymentKit.VISUALIZER_EVENTS.USER_SESSION_STARTED,
*
* // if you want to handle event of specific visualizer instance
* visualizer
* );
*/
const subscribe = (callback, eventName = null, visualizer = null) => {
if (typeof callback !== 'function') {
console.error(`Passed callback is not a function.`);
}
if (visualizer !== null && !visualizer._isInstanceOfVisualizer) {
console.error(`Wrong value passed for visualizer argument`);
}
if (eventName !== null && !hasValue(VISUALIZER_EVENTS, eventName) && !hasValue(PRIVATE_EVENTS, eventName)) {
console.error(`Unknow event type ${eventName}.`);
}
const subscriptionId = Symbol();
if (visualizer !== null && visualizer._isInstanceOfVisualizer) {
visualizer._registerLocalSubscription(subscriptionId);
}
subscribers_.set(subscriptionId, { callback, eventName, visualizer });
return subscriptionId;
}
/**
* Unsubscribes from an event using the provided subscription ID.
* @function unsubscribe
* @memberof WizartDeploymentKit.EventBus
* @param {symbol} subscriptionId - The unique ID of the subscription to remove.
*
* @example
* WizartDeploymentKit.EventBus.unsubscribe(subscriptionId);
*/
const unsubscribe = (subscriptionId) => {
subscribers_.delete(subscriptionId);
}
/**
* @ignore
*/
const initEventListener_ = () => {
const WIZART_EVENT_NAME = 'wizart_analytics';
window.addEventListener("message", (event) => {
const { data={}, source } = event;
event.stopPropagation();
let wizartEventName = data.analyticsEventName;
if (!wizartEventName && hasValue(PRIVATE_EVENTS, data.eventName)) {
wizartEventName = data.eventName;
}
if (wizartEventName) {
subscribers_.forEach((subscriber, subscriptionId) => {
const { callback, eventName, visualizer } = subscriber;
const isEventMatch = !eventName || eventName === wizartEventName;
const isVisualizerMatch = !visualizer || (visualizer.isLoaded && source === visualizer.iframe.contentWindow);
if (isEventMatch && isVisualizerMatch) {
callback(new WizartEvent(getKey(VISUALIZER_EVENTS, wizartEventName), data.payload));
}
});
}
});
};
initEventListener_();
const EventBus = {
pushEvent,
subscribe,
unsubscribe
};
export {
EventBus,
WizartEvent
}