Exemple #1
0
  /**
   * Will return a Stale resource when a given resource cannot be found by the
   * supplied descriptor.
   */
  fetch(descriptor) {
    var fragmentCache = this._getFragment(descriptor.partial)
      , resourceId = descriptor.id
      , result = null
      , resource = null
      , fragments, i, data, entry;

    result = new RefraxFragmentResult();

    if (resourceId) {
      resource = fragmentCache[resourceId];

      if (resource) {
        result.status = resource.status;
        result.timestamp = resource.timestamp;
        result.data = resource.data;
      }

      if (!result.data) {
        // Create a new list of fragments with our global default being last at highest priority.
        fragments = [].concat(descriptor.fragments, FRAGMENT_DEFAULT);

        for (i = 0; i < fragments.length; i++) {
          fragmentCache = this._getFragment(fragments[i])[resourceId];

          if (fragmentCache && fragmentCache.data) {
            result.data = RefraxTools.extend({}, result.data || {}, fragmentCache.data || {});
            result.status = STATUS_PARTIAL;
          }
        }
      }
    }
    else if (descriptor.basePath) {
      resource = this.queries[descriptor.basePath];
      if (resource) {
        result.status = resource.status;
        result.timestamp = resource.timestamp;
      }

      if (!resource || !(data = resource.data)) {
        return result;
      }

      if (descriptor.classify === CLASSIFY_COLLECTION) {
        result.data = RefraxTools.map(data || [], function(id) {
          var entry = fragmentCache[id];

          if (!entry) {
            throw new TypeError(
              'RefraxFragmentCache:fetch - Unexpected error, failure to find collection entry for `' + id + '`.'
            );
          }

          return RefraxTools.extend({}, entry.data);
        });
      }
      else if (descriptor.classify === CLASSIFY_ITEM) {
        entry = fragmentCache[data];
        if (!entry) {
          throw new TypeError(
            'RefraxFragmentCache:fetch - Unexpected error, failure to find entry for `' + data + '`.'
          );
        }

        result.data = RefraxTools.extend({}, entry.data);
      }
      else {
        if (RefraxTools.isArray(data)) {
          data = [].concat(data);
        }
        else if (RefraxTools.isObject(data)) {
          data = RefraxTools.extend({}, data);
        }

        result.data = data;
      }
    }

    // If we are expecting a collection let's ensure we are an array atleast
    if (!result.data && descriptor.classify === CLASSIFY_COLLECTION) {
      result.data = [];
    }

    return result;
  }
Exemple #2
0
  /**
   * Update the content for a given resource.
   */
  update(descriptor, data, status) {
    var self = this
      , fragmentCache = this._getFragment(descriptor.partial)
      , queryData
      , resourcePath = descriptor.basePath
      , result
      , touchedIds = []
      , dataId = null;

    // if no data is present (ie a 204 response) our data then becomes stale
    result = {
      status: status || STATUS_COMPLETE,
      timestamp: data ? Date.now() : TIMESTAMP_STALE
    };

    // Fragments
    if (descriptor.classify === CLASSIFY_COLLECTION && data) {
      if (!RefraxTools.isArray(data) && !RefraxTools.isPlainObject(data)) {
        throw new TypeError(
          'RefraxFragmentCache:update expected collection compatible type of Array/Object\n\r' +
          'basePath: ' + resourcePath + '\n\r' +
          'found: `' + typeof(data) + '`'
        );
      }

      if (RefraxTools.isArray(data)) {
        dataId = RefraxTools.map(data, function(item) {
          return self._updateFragmentCache(fragmentCache, descriptor, result, item, touchedIds);
        });
      }
      else {
        dataId = this._updateFragmentCache(fragmentCache, descriptor, result, data, touchedIds);
      }
    }
    else if (descriptor.classify === CLASSIFY_ITEM) {
      dataId = this._updateFragmentCache(fragmentCache, descriptor, result, data, touchedIds);
    }

    // Queries
    if (resourcePath) {
      queryData = this.queries[resourcePath] && this.queries[resourcePath].data;

      // from a REST perspective collections are typically modified when creating into them
      if (descriptor.classify === CLASSIFY_COLLECTION) {
        if (dataId) {
          queryData = RefraxTools.concatUnique(queryData, dataId);
        }
        // if no data was received creating into a collection we can mark it as stale
        else {
          result.status = STATUS_STALE;
          result.timestamp = TIMESTAMP_STALE;
        }
      }
      else if (descriptor.classify === CLASSIFY_ITEM) {
        queryData = dataId;
      }
      else if (data) {
        if (descriptor.cacheStrategy === CACHE_STRATEGY_MERGE) {
          if (RefraxTools.isArray(queryData) || RefraxTools.isArray(data)) {
            queryData = RefraxTools.concatUnique(queryData, data);
          }
          else {
            queryData = RefraxTools.extend(queryData || {}, data);
          }
        }
        else {
          queryData = data;
        }
      }

      this.queries[resourcePath] = RefraxTools.extend({}, result, {
        data: queryData
      });
    }

    return touchedIds;
  }