Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

pfchangs / react-relay   js

Repository URL to install this package:

Version: 0.7.1-ccinternal 

/ lib / GraphQLStoreChangeEmitter.js

/**
 * Copyright 2013-2015, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule GraphQLStoreChangeEmitter
 * @typechecks
 * 
 */

'use strict';

var _classCallCheck = require('babel-runtime/helpers/class-call-check')['default'];

Object.defineProperty(exports, '__esModule', {
  value: true
});
var ErrorUtils = require('fbjs/lib/ErrorUtils');

var resolveImmediate = require('fbjs/lib/resolveImmediate');

/**
 * Asynchronous change emitter for nodes stored in the Relay cache.
 *
 * Changes are produced by `RelayStoreData` after writing query and mutation
 * payloads into the store and consumed by `GraphQLStoreQueryResolver`, which
 * subscribes to all records that are part of an active query result set.
 *
 * @internal
 */

var GraphQLStoreChangeEmitter = (function () {
  function GraphQLStoreChangeEmitter(rangeData) {
    _classCallCheck(this, GraphQLStoreChangeEmitter);

    this._batchUpdate = function (callback) {
      return callback();
    };
    this._executingIDs = {};
    this._rangeData = rangeData;
    this._scheduledIDs = null;
    this._subscribers = [];
  }

  GraphQLStoreChangeEmitter.prototype.addListenerForIDs = function addListenerForIDs(ids, callback) {
    var _this = this;

    var subscribedIDs = ids.map(function (id) {
      return _this._getBroadcastID(id);
    });
    var index = this._subscribers.length;
    this._subscribers.push({ subscribedIDs: subscribedIDs, callback: callback });
    return {
      remove: function remove() {
        delete _this._subscribers[index];
      }
    };
  };

  GraphQLStoreChangeEmitter.prototype.broadcastChangeForID = function broadcastChangeForID(id) {
    var _this2 = this;

    var scheduledIDs = this._scheduledIDs;
    if (scheduledIDs == null) {
      resolveImmediate(function () {
        return _this2._processBroadcasts();
      });
      scheduledIDs = this._scheduledIDs = {};
    }
    // Record index of the last subscriber so we do not later unintentionally
    // invoke callbacks that were subscribed after this broadcast.
    scheduledIDs[this._getBroadcastID(id)] = this._subscribers.length - 1;
  };

  GraphQLStoreChangeEmitter.prototype.injectBatchingStrategy = function injectBatchingStrategy(batchStrategy) {
    this._batchUpdate = batchStrategy;
  };

  GraphQLStoreChangeEmitter.prototype._processBroadcasts = function _processBroadcasts() {
    var _this3 = this;

    if (this._scheduledIDs) {
      this._executingIDs = this._scheduledIDs;
      this._scheduledIDs = null;
      this._batchUpdate(function () {
        return _this3._processSubscribers();
      });
    }
  };

  /**
   * Exposed for profiling reasons.
   * @private
   */

  GraphQLStoreChangeEmitter.prototype._processSubscribers = function _processSubscribers() {
    var _this4 = this;

    this._subscribers.forEach(function (subscriber, subscriberIndex) {
      return _this4._processSubscriber(subscriber, subscriberIndex);
    });
  };

  GraphQLStoreChangeEmitter.prototype._processSubscriber = function _processSubscriber(_ref, subscriberIndex) {
    var subscribedIDs = _ref.subscribedIDs;
    var callback = _ref.callback;

    for (var broadcastID in this._executingIDs) {
      if (this._executingIDs.hasOwnProperty(broadcastID)) {
        var broadcastIndex = this._executingIDs[broadcastID];
        if (broadcastIndex < subscriberIndex) {
          // Callback was subscribed after this particular broadcast.
          break;
        }
        if (subscribedIDs.indexOf(broadcastID) >= 0) {
          ErrorUtils.applyWithGuard(callback, null, null, null, 'GraphQLStoreChangeEmitter');
          break;
        }
      }
    }
  };

  /**
   * Ranges publish events for the entire range, not the specific view of that
   * range. For example, if "client:1" is a range, the event is on "client:1",
   * not "client:1_first(5)".
   */

  GraphQLStoreChangeEmitter.prototype._getBroadcastID = function _getBroadcastID(id) {
    return this._rangeData.getCanonicalClientID(id);
  };

  return GraphQLStoreChangeEmitter;
})();

module.exports = GraphQLStoreChangeEmitter;