Home Reference Source

src/contacts/PresenceQueue.js


import {Queue} from '../utils/Queue';

/**
 * Class that interacts with WacProxy to subscribe and get presences.
 * These operations are not done immediately, the consecutive calls are queued
 * to use a single call.
 * All resolutions are stored in a collection so that future calls do not require
 * a new call to WacProxy.
 * @private
 */
export class PresenceQueue {

	/**
	 * Create a new presence retrieve queue.
	 * @protected
	 * @param {PresenceService} presenceService The wac proxy instance to interact.
	 * @param {PresenceCollection} collection The collection where resolved elements
	 * are stored.
	 */
	constructor(presenceService, collection) {

		/**
		 * @private
		 * @type {PresenceService}
		 */
		this.presenceService = presenceService;

		/**
		 * @private
		 * @type {PresenceCollection}
		 */
		this._collection = collection;

		/**
		 * List of queued request.
		 * @private
		 * @type {Array<ResolveQueueItem>}
		 */
		this._queue = new Queue(this);
	}

	/**
	 * Add a new subscription request to subscription queue.
	 * When commit timer exists, it is canceled. A new commit timer is created.
	 * @param {String} address The presence address`to start receiving presence updates.
	 * @return {Promise<object>} resolved on success with subscribed presence if subscription
	 * success.
	 */
	subscribeToPresence(address) {
		return this._queue.addToQueue(address);
	}

	/**
	 * Remove a presence subscription.
	 * @param {String} address The presence address to stop receiving presence updates.
	 * @return {Promise} resolved once unsubscription success.
	 */
	unsubscribeFromPresence(address) {
		return this.presenceService.destroy(address);
	}

	/**
	 * Method that subscribes to any queued subscription request.
	 * When a response is received from WacStack local presence collection is updated.
	 * @private
	 */
	commit(pending) {
		this.presenceService.subscribeToPresences(pending.map(x => x.data)).then((presences) => {
			presences.forEach(x => this._collection.updatePresence(x));
			pending.forEach(x => x.resolve(this._collection.getPresence(x.data)));
		}).catch((error) => {
			pending.forEach(x => x.reject(error));
		});
	}
}