Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/p-event/index.js b/node_modules/p-event/index.js
new file mode 100644
index 0000000..24d044a
--- /dev/null
+++ b/node_modules/p-event/index.js
@@ -0,0 +1,72 @@
+'use strict';
+const pTimeout = require('p-timeout');
+
+module.exports = (emitter, event, opts) => {
+	let cancel;
+
+	const ret = new Promise((resolve, reject) => {
+		if (typeof opts === 'function') {
+			opts = {filter: opts};
+		}
+
+		opts = Object.assign({
+			rejectionEvents: ['error'],
+			multiArgs: false
+		}, opts);
+
+		let addListener = emitter.on || emitter.addListener || emitter.addEventListener;
+		let removeListener = emitter.off || emitter.removeListener || emitter.removeEventListener;
+
+		if (!addListener || !removeListener) {
+			throw new TypeError('Emitter is not compatible');
+		}
+
+		addListener = addListener.bind(emitter);
+		removeListener = removeListener.bind(emitter);
+
+		const resolveHandler = function (value) {
+			if (opts.multiArgs) {
+				value = [].slice.apply(arguments);
+			}
+
+			if (opts.filter && !opts.filter(value)) {
+				return;
+			}
+
+			cancel();
+			resolve(value);
+		};
+
+		const rejectHandler = function (reason) {
+			cancel();
+
+			if (opts.multiArgs) {
+				reject([].slice.apply(arguments));
+			} else {
+				reject(reason);
+			}
+		};
+
+		cancel = () => {
+			removeListener(event, resolveHandler);
+
+			for (const rejectionEvent of opts.rejectionEvents) {
+				removeListener(rejectionEvent, rejectHandler);
+			}
+		};
+
+		addListener(event, resolveHandler);
+
+		for (const rejectionEvent of opts.rejectionEvents) {
+			addListener(rejectionEvent, rejectHandler);
+		}
+	});
+
+	ret.cancel = cancel;
+
+	if (typeof opts.timeout === 'number') {
+		return pTimeout(ret, opts.timeout);
+	}
+
+	return ret;
+};