code: function ExecutionCache() {
    var cache = {};
  
    function getKey(query) {
      return query.queryKey + '(' + JSON.stringify(query.queryParams) + ')'
    }
  
    function get(query) {
      return cache[getKey(query)]
    }
  
    this.execute = function (query) {
      var query = _.cloneDeep(query);
      var execution = get(query);
      if (execution) {
        var requestedKeys = _.keys(query.shape);
        if (_.intersection(_.keys(execution.shape), requestedKeys).length != requestedKeys.length) {
          // TODO we probably should also merge the nested shape
          var newShape = _.assign(execution.shape, query.shape);
          query.shape = newShape;
          execution = {
            shape: newShape,
            promise: getHandler(query.name, query.queryKey)(query.shape, query.queryParams, query.type)
          }
        }
      } else {
        execution = {
          shape: query.shape,
          promise: getHandler(query.name, query.queryKey)(query.shape, query.queryParams, query.type)
        };
      }
      cache[getKey(query)] = execution;
      return execution;
    };
  
    this.get = get;
    this.getKey = getKey;
    return this;
  }
docs: /* Takes queries and stores their results collected by query name and query parameters