Home Reference Source

src/users/ResolveQueue.js

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

/**
 * Class that interacts with WacProxy to translate addresses to WAC users.
 * This translation is 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 ResolveQueue {

	/**
	 * Creates a new resolver queue
	 * @protected
	 * @param {WacProxy} stack The wac proxy instance to interact.
	 * @param {UserCollection} collection The collection where resolved elements
	 * are stored.
	 */
	constructor(stack, collection) {

		/**
		 * @private
		 * @type {WacProxy}
		 */
		this._stack = stack;

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

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

	/**
	 * Add a new resolution request to queue.
	 * If we are subscribed to requested address, undefined is returned.
	 * When commit timer exists, it is canceled. A new commit timer is created.
	 * @param {String} address element to resolve.
	 * @return {Promise<User|undefined>} resolved on success with resolved user if resolution
	 * success, undefined if no user was found or rejected with an error if something fails.
	 */
	resolve(address) {
		address = address.toLowerCase();
		if (this._collection.isSubscribedTo(address)) {
			return Promise.resolve();
		}
		return this._queue.addToQueue(address);
	}

	/**
	 * Method that resolves any queued resolution request.
	 * When a response is received from WacStack resolved and subscribed collections are updated.
	 * @private
	 */
	commit(pending) {
		this._stack.getResolver().resolveUsers(pending.map(x => x.data)).then((list) => {
			list.resolved.forEach(x => this._collection.addUser(x));
			this._collection.updateSubscribed(list.subscribed);
			pending.forEach(x => x.resolve(this._collection.resolve(x.data)));
		}).catch((error) => {
			pending.forEach(x => x.reject(error));
		});
	}
}