src/indexeddb.js
function (nodes) {
    return new Promise((resolve, reject) => {

      let transaction = this.db.transaction(['nodes'], 'readwrite');
      let nodesStore = transaction.objectStore('nodes');
      let startTime = new Date().getTime();

      this.putsRunning++;

      log('[IndexedDB] Starting put', nodes, this.putsRunning);

      for (var path in nodes) {
        var node = nodes[path];
        if(typeof(node) === 'object') {
          try {
            nodesStore.put(node);
          } catch(e) {
            log('[IndexedDB] Error while putting', node, e);
            throw e;
          }
        } else {
          try {
            nodesStore.delete(path);
          } catch(e) {
            log('[IndexedDB] Error while removing', nodesStore, node, e);
            throw e;
          }
        }
      }

      transaction.oncomplete = function () {
        this.putsRunning--;
        log('[IndexedDB] Finished put', nodes, this.putsRunning, (new Date().getTime() - startTime)+'ms');
        resolve();
      }.bind(this);

      transaction.onerror = function () {
        this.putsRunning--;
        reject('transaction error');
      }.bind(this);

      transaction.onabort = function () {
        reject('transaction abort');
        this.putsRunning--;
      }.bind(this);

    });
  }
function (nodes) {
    return new Promise((resolve, reject) => {

      let transaction = this.db.transaction(['nodes'], 'readwrite');
      let nodesStore = transaction.objectStore('nodes');
      let startTime = new Date().getTime();

      this.putsRunning++;

      log('[IndexedDB] Starting put', nodes, this.putsRunning);

      for (var path in nodes) {
        var node = nodes[path];
        if(typeof(node) === 'object') {
          try {
            nodesStore.put(node);
          } catch(e) {
            log('[IndexedDB] Error while putting', node, e);
            throw e;
          }
        } else {
          try {
            nodesStore.delete(path);
          } catch(e) {
            log('[IndexedDB] Error while removing', nodesStore, node, e);
            throw e;
          }
        }
      }

      transaction.oncomplete = function () {
        this.putsRunning--;
        log('[IndexedDB] Finished put', nodes, this.putsRunning, (new Date().getTime() - startTime)+'ms');
        resolve();
      }.bind(this);

      transaction.onerror = function () {
        this.putsRunning--;
        reject('transaction error');
      }.bind(this);

      transaction.onabort = function () {
        reject('transaction abort');
        this.putsRunning--;
      }.bind(this);

    });
  }
TODO: Document