src/EventStore.js
function setupOneTimeEmitterSubscription(emitter, messageTypes, filter, handler) {
	if (typeof emitter !== 'object' || !emitter)
		throw new TypeError('emitter argument must be an Object');
	if (!Array.isArray(messageTypes) || messageTypes.some(m => !m || typeof m !== 'string'))
		throw new TypeError('messageTypes argument must be an Array of non-empty Strings');
	if (handler && typeof handler !== 'function')
		throw new TypeError('handler argument, when specified, must be a Function');
	if (filter && typeof filter !== 'function')
		throw new TypeError('filter argument, when specified, must be a Function');

	return new Promise(resolve => {

		// handler will be invoked only once,
		// even if multiple events have been emitted before subscription was destroyed
		// https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener
		let handled = false;

		function filteredHandler(event) {
			if (filter && !filter(event)) return;
			if (handled) return;
			handled = true;

			for (const messageType of messageTypes)
				emitter.off(messageType, filteredHandler);

			debug('\'%s\' received, one-time subscription to \'%s\' removed', event.type, messageTypes.join(','));

			if (handler)
				handler(event);

			resolve(event);
		}

		for (const messageType of messageTypes)
			emitter.on(messageType, filteredHandler);

		debug('set up one-time %s to \'%s\'', filter ? 'filtered subscription' : 'subscription', messageTypes.join(','));
	});
}
function setupOneTimeEmitterSubscription(emitter, messageTypes, filter, handler) {
	if (typeof emitter !== 'object' || !emitter)
		throw new TypeError('emitter argument must be an Object');
	if (!Array.isArray(messageTypes) || messageTypes.some(m => !m || typeof m !== 'string'))
		throw new TypeError('messageTypes argument must be an Array of non-empty Strings');
	if (handler && typeof handler !== 'function')
		throw new TypeError('handler argument, when specified, must be a Function');
	if (filter && typeof filter !== 'function')
		throw new TypeError('filter argument, when specified, must be a Function');

	return new Promise(resolve => {

		// handler will be invoked only once,
		// even if multiple events have been emitted before subscription was destroyed
		// https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener
		let handled = false;

		function filteredHandler(event) {
			if (filter && !filter(event)) return;
			if (handled) return;
			handled = true;

			for (const messageType of messageTypes)
				emitter.off(messageType, filteredHandler);

			debug('\'%s\' received, one-time subscription to \'%s\' removed', event.type, messageTypes.join(','));

			if (handler)
				handler(event);

			resolve(event);
		}

		for (const messageType of messageTypes)
			emitter.on(messageType, filteredHandler);

		debug('set up one-time %s to \'%s\'', filter ? 'filtered subscription' : 'subscription', messageTypes.join(','));
	});
}
function setupOneTimeEmitterSubscription ( emitter , messageTypes , filter , handler ) { if ( typeof emitter !== 'object' || ! emitter ) throw new TypeError ( 'emitter argument must be an Object' ) ; if ( ! Array . isArray ( messageTypes ) || messageTypes . some ( m => ! m || typeof m !== 'string' ) ) throw new TypeError ( 'messageTypes argument must be an Array of non-empty Strings' ) ; if ( handler && typeof handler !== 'function' ) throw new TypeError ( 'handler argument, when specified, must be a Function' ) ; if ( filter && typeof filter !== 'function' ) throw new TypeError ( 'filter argument, when specified, must be a Function' ) ; return new Promise ( resolve => { // handler will be invoked only once, // even if multiple events have been emitted before subscription was destroyed // https://nodejs.org/api/events.html#events_emitter_removelistener_eventname_listener let handled = false ; function filteredHandler ( event ) { if ( filter && ! filter ( event ) ) return ; if ( handled ) return ; handled = true ; for ( const messageType of messageTypes ) emitter . off ( messageType , filteredHandler ) ; debug ( '\'%s\' received, one-time subscription to \'%s\' removed' , event . type , messageTypes . join ( ',' ) ) ; if ( handler ) handler ( event ) ; resolve ( event ) ; } for ( const messageType of messageTypes ) emitter . on ( messageType , filteredHandler ) ; debug ( 'set up one-time %s to \'%s\'' , filter ? 'filtered subscription' : 'subscription' , messageTypes . join ( ',' ) ) ; } ) ; }
Create one-time eventEmitter subscription for one or multiple events that match a filter

@param {IEventEmitter} emitter
@param {string[]} messageTypes Array of event type to subscribe to
@param {function(IEvent):any} [handler] Optional handler to execute for a first event received
@param {function(IEvent):boolean} [filter] Optional filter to apply before executing a handler
@return {Promise<IEvent>} Resolves to first event that passes filter
Create one - time eventEmitter subscription for one or multiple events that match a filter