aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/store/store.js
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2014-12-10 00:47:05 +0100
committerMaximilian Hils <git@maximilianhils.com>2014-12-10 00:47:05 +0100
commite12bf19e35867f3ea69f45054decb024a75fc2b4 (patch)
tree8201f5fd9f07d46a1a659bdfa93b2176066f4961 /web/src/js/store/store.js
parent05bc7e8cd8382aabdd44f7bc569d2fd421c26f21 (diff)
downloadmitmproxy-e12bf19e35867f3ea69f45054decb024a75fc2b4.tar.gz
mitmproxy-e12bf19e35867f3ea69f45054decb024a75fc2b4.tar.bz2
mitmproxy-e12bf19e35867f3ea69f45054decb024a75fc2b4.zip
web: add event store, fix all those bugs
Diffstat (limited to 'web/src/js/store/store.js')
-rw-r--r--web/src/js/store/store.js123
1 files changed, 123 insertions, 0 deletions
diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js
new file mode 100644
index 00000000..da288a5d
--- /dev/null
+++ b/web/src/js/store/store.js
@@ -0,0 +1,123 @@
+function Store() {
+ this._views = [];
+ this.reset();
+}
+_.extend(Store.prototype, {
+ add: function (elem) {
+ if (elem.id in this._pos_map) {
+ return;
+ }
+
+ this._pos_map[elem.id] = this._list.length;
+ this._list.push(elem);
+ for (var i = 0; i < this._views.length; i++) {
+ this._views[i].add(elem);
+ }
+ },
+ update: function (elem) {
+ if (!(elem.id in this._pos_map)) {
+ return;
+ }
+
+ this._list[this._pos_map[elem.id]] = elem;
+ for (var i = 0; i < this._views.length; i++) {
+ this._views[i].update(elem);
+ }
+ },
+ remove: function (elem_id) {
+ if (!(elem.id in this._pos_map)) {
+ return;
+ }
+
+ this._list.splice(this._pos_map[elem_id], 1);
+ this._build_map();
+ for (var i = 0; i < this._views.length; i++) {
+ this._views[i].remove(elem_id);
+ }
+ },
+ reset: function (elems) {
+ this._list = elems || [];
+ this._build_map();
+ for (var i = 0; i < this._views.length; i++) {
+ this._views[i].recalculate(this._list);
+ }
+ },
+ _build_map: function () {
+ this._pos_map = {};
+ for (var i = 0; i < this._list.length; i++) {
+ var elem = this._list[i];
+ this._pos_map[elem.id] = i;
+ }
+ },
+ get: function (elem_id) {
+ return this._list[this._pos_map[elem_id]];
+ },
+ index: function(elem_id) {
+ return this._pos_map[elem_id];
+ }
+});
+
+
+function LiveStore(type) {
+ Store.call(this);
+ this.type = type;
+
+ this._updates_before_fetch = undefined;
+ this._fetchxhr = false;
+
+ this.handle = this.handle.bind(this);
+ AppDispatcher.register(this.handle);
+
+ // Avoid double-fetch on startup.
+ if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) {
+ this.fetch();
+ }
+}
+_.extend(LiveStore.prototype, Store.prototype, {
+ handle: function (event) {
+ if (event.type === ActionTypes.CONNECTION_OPEN) {
+ return this.fetch();
+ }
+ if (event.type === this.type) {
+ if (event.cmd === StoreCmds.RESET) {
+ this.fetch();
+ } else if (this._updates_before_fetch) {
+ console.log("defer update", event);
+ this._updates_before_fetch.push(event);
+ } else {
+ this[event.cmd](event.data);
+ }
+ }
+ },
+ close: function () {
+ AppDispatcher.unregister(this.handle);
+ },
+ fetch: function () {
+ console.log("fetch " + this.type);
+ if (this._fetchxhr) {
+ this._fetchxhr.abort();
+ }
+ this._fetchxhr = $.getJSON("/" + this.type, this.handle_fetch.bind(this));
+ this._updates_before_fetch = []; // (JS: empty array is true)
+ },
+ handle_fetch: function (data) {
+ this._fetchxhr = false;
+ console.log(this.type + " fetched.", this._updates_before_fetch);
+ this.reset(data.list);
+ var updates = this._updates_before_fetch;
+ this._updates_before_fetch = false;
+ for (var i = 0; i < updates.length; i++) {
+ this.handle(updates[i]);
+ }
+ },
+});
+
+
+function FlowStore() {
+ return new LiveStore(ActionTypes.FLOW_STORE);
+}
+
+
+function EventLogStore() {
+ return new LiveStore(ActionTypes.EVENT_STORE);
+} \ No newline at end of file