"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const PubSub = require("pubsub-js");
const loggingService_1 = require("./loggingService");
class EventService {
    /**
     * Send the given payload to subscribers of the given topic.
     * @param topic See [subscribe](EventService#subscribe)
     * @param payload Sent in the subscription callback.
     * @returns True if there are any subscribers
     */
    static publish(topic, payload) {
        loggingService_1.LoggingService.debug(`EventService: publishing ${topic}`);
        return PubSub.publish(topic, payload);
    }
    /**
     * Subscribe to the given topic or array of topics.
     * @param topics Identifies the event(s) to which you wish to subscribe
     * @param callback The function to call when the requested events are published
     * @returns An interface with `.unsubscribe()`.  Be sure to call it!
     */
    static subscribe(topics, callback) {
        return Array.isArray(topics) ?
            EventService.aggregate(topics, callback) :
            new EventSubscription(PubSub.subscribe(topics, callback));
    }
    /**
     * Remove all subscriptions
     */
    static clearAllSubscriptions() {
        PubSub.clearAllSubscriptions();
    }
    /**
     * Removes a subscription.
     * When passed a token, removes a specific subscription,
     * when passed a callback, removes all subscriptions for that callback,
     * when passed a topic, removes all subscriptions for the topic hierarchy.
     *
     * @param key - A token, function or topic to unsubscribe.
     */
    static unsubscribe(key) {
        PubSub.unsubscribe(key);
    }
    /**
     * Subscribe to multiple topics with the single given callback.
     * @param topics topic or collection of topics
     * @param callback Callback to handle them all
     * @returns An interface with `.unsubscribe()`.  Be sure to call it!
     */
    static aggregate(topics, callback) {
        return new SubscriptionCollection(topics, callback);
    }
}
exports.EventService = EventService;
/**
 * Creates a collection of subscriptions to which one can unsubscribe all at once.
 */
class SubscriptionCollection {
    constructor(topics, callback) {
        this.subscriptions = new Set();
        if (topics) {
            if (!callback) {
                throw new Error("SubscriptionCollection: callback is not set");
            }
            this.subscribe(topics, callback);
        }
    }
    /**
     * Subscribe a single callback to a set of events
     * @param topics
     * @param callback
     */
    subscribe(topics, callback) {
        if (!Array.isArray(topics)) {
            topics = [topics];
        }
        topics.forEach((topic) => {
            const subscriptionKey = PubSub.subscribe(topic, callback);
            this.subscriptions.add(new EventSubscription(subscriptionKey));
        });
    }
    /**
     * Unsubscribe from all of the events
     */
    unsubscribe() {
        // timeout to allow lingering events to be handled before unsubscribing
        setTimeout(() => {
            this.subscriptions.forEach((s) => {
                s.unsubscribe();
            });
            this.subscriptions.clear();
        }, 0);
    }
}
exports.SubscriptionCollection = SubscriptionCollection;
class EventSubscription {
    constructor(key) {
        this.key = key;
    }
    unsubscribe() {
        PubSub.unsubscribe(this.key);
    }
}
exports.EventSubscription = EventSubscription;
//# sourceMappingURL=eventService.js.map