Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/p-cancelable/index.js b/node_modules/p-cancelable/index.js
new file mode 100644
index 0000000..406367d
--- /dev/null
+++ b/node_modules/p-cancelable/index.js
@@ -0,0 +1,77 @@
+'use strict';
+
+class CancelError extends Error {
+	constructor() {
+		super('Promise was canceled');
+		this.name = 'CancelError';
+	}
+}
+
+class PCancelable {
+	static fn(fn) {
+		return function () {
+			const args = [].slice.apply(arguments);
+			return new PCancelable((onCancel, resolve, reject) => {
+				args.unshift(onCancel);
+				fn.apply(null, args).then(resolve, reject);
+			});
+		};
+	}
+
+	constructor(executor) {
+		this._pending = true;
+		this._canceled = false;
+
+		this._promise = new Promise((resolve, reject) => {
+			this._reject = reject;
+
+			return executor(
+				fn => {
+					this._cancel = fn;
+				},
+				val => {
+					this._pending = false;
+					resolve(val);
+				},
+				err => {
+					this._pending = false;
+					reject(err);
+				}
+			);
+		});
+	}
+
+	then() {
+		return this._promise.then.apply(this._promise, arguments);
+	}
+
+	catch() {
+		return this._promise.catch.apply(this._promise, arguments);
+	}
+
+	cancel() {
+		if (!this._pending || this._canceled) {
+			return;
+		}
+
+		if (typeof this._cancel === 'function') {
+			try {
+				this._cancel();
+			} catch (err) {
+				this._reject(err);
+			}
+		}
+
+		this._canceled = true;
+		this._reject(new CancelError());
+	}
+
+	get canceled() {
+		return this._canceled;
+	}
+}
+
+Object.setPrototypeOf(PCancelable.prototype, Promise.prototype);
+
+module.exports = PCancelable;
+module.exports.CancelError = CancelError;