UNPKG

relay-runtime

Version:

A core runtime for building GraphQL-driven applications.

215 lines (214 loc) • 10.4 kB
'use strict'; var _global$ErrorUtils$ap, _global$ErrorUtils; var RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator'); var RelayRecordSourceProxy = require('../mutations/RelayRecordSourceProxy'); var RelayRecordSourceSelectorProxy = require('../mutations/RelayRecordSourceSelectorProxy'); var RelayFeatureFlags = require('../util/RelayFeatureFlags'); var RelayReader = require('./RelayReader'); var RelayRecordSource = require('./RelayRecordSource'); var invariant = require('invariant'); var warning = require("fbjs/lib/warning"); var _global = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : undefined; var applyWithGuard = (_global$ErrorUtils$ap = _global === null || _global === void 0 ? void 0 : (_global$ErrorUtils = _global.ErrorUtils) === null || _global$ErrorUtils === void 0 ? void 0 : _global$ErrorUtils.applyWithGuard) !== null && _global$ErrorUtils$ap !== void 0 ? _global$ErrorUtils$ap : function (callback, context, args, onError, name) { return callback.apply(context, args); }; var RelayPublishQueue = /*#__PURE__*/function () { function RelayPublishQueue(store, handlerProvider, getDataID, missingFieldHandlers, log) { this._hasStoreSnapshot = false; this._handlerProvider = handlerProvider || null; this._pendingBackupRebase = false; this._pendingData = new Set(); this._pendingOptimisticUpdates = new Set(); this._store = store; this._appliedOptimisticUpdates = new Set(); this._gcHold = null; this._getDataID = getDataID; this._missingFieldHandlers = missingFieldHandlers; this._log = log; } var _proto = RelayPublishQueue.prototype; _proto.applyUpdate = function applyUpdate(updater) { !(!this._appliedOptimisticUpdates.has(updater) && !this._pendingOptimisticUpdates.has(updater)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayPublishQueue: Cannot apply the same update function more than ' + 'once concurrently.') : invariant(false) : void 0; this._pendingOptimisticUpdates.add(updater); }; _proto.revertUpdate = function revertUpdate(updater) { if (this._pendingOptimisticUpdates.has(updater)) { this._pendingOptimisticUpdates["delete"](updater); } else if (this._appliedOptimisticUpdates.has(updater)) { this._pendingBackupRebase = true; this._appliedOptimisticUpdates["delete"](updater); } }; _proto.revertAll = function revertAll() { this._pendingBackupRebase = true; this._pendingOptimisticUpdates.clear(); this._appliedOptimisticUpdates.clear(); }; _proto.commitPayload = function commitPayload(operation, payload, updater) { this._pendingBackupRebase = true; this._pendingData.add({ kind: 'payload', operation: operation, payload: payload, updater: updater }); }; _proto.commitUpdate = function commitUpdate(updater) { this._pendingBackupRebase = true; this._pendingData.add({ kind: 'updater', updater: updater }); }; _proto.commitSource = function commitSource(source) { this._pendingBackupRebase = true; this._pendingData.add({ kind: 'source', source: source }); }; _proto.run = function run(sourceOperation) { var runWillClearGcHold = this._appliedOptimisticUpdates === 0 && !!this._gcHold; var runIsANoop = !this._pendingBackupRebase && this._pendingOptimisticUpdates.size === 0 && !runWillClearGcHold; process.env.NODE_ENV !== "production" ? warning(!runIsANoop, 'RelayPublishQueue.run was called, but the call would have been a noop.') : void 0; RelayFeatureFlags.DISALLOW_NESTED_UPDATES ? !(this._isRunning !== true) ? process.env.NODE_ENV !== "production" ? invariant(false, 'A store update was detected within another store update. Please ' + "make sure new store updates aren't being executed within an " + 'updater function for a different update.') : invariant(false) : void 0 : process.env.NODE_ENV !== "production" ? warning(this._isRunning !== true, 'A store update was detected within another store update. Please ' + "make sure new store updates aren't being executed within an " + 'updater function for a different update.') : void 0; this._isRunning = true; if (runIsANoop) { this._isRunning = false; return []; } if (this._pendingBackupRebase) { if (this._hasStoreSnapshot) { this._store.restore(); this._hasStoreSnapshot = false; } } var invalidatedStore = this._commitData(); if (this._pendingOptimisticUpdates.size || this._pendingBackupRebase && this._appliedOptimisticUpdates.size) { if (!this._hasStoreSnapshot) { this._store.snapshot(); this._hasStoreSnapshot = true; } this._applyUpdates(); } this._pendingBackupRebase = false; if (this._appliedOptimisticUpdates.size > 0) { if (!this._gcHold) { this._gcHold = this._store.holdGC(); } } else { if (this._gcHold) { this._gcHold.dispose(); this._gcHold = null; } } this._isRunning = false; return this._store.notify(sourceOperation, invalidatedStore); }; _proto._publishSourceFromPayload = function _publishSourceFromPayload(pendingPayload) { var _this = this; var payload = pendingPayload.payload, operation = pendingPayload.operation, updater = pendingPayload.updater; var source = payload.source, fieldPayloads = payload.fieldPayloads; var mutator = new RelayRecordSourceMutator(this._store.getSource(), source); var recordSourceProxy = new RelayRecordSourceProxy(mutator, this._getDataID, this._handlerProvider, this._missingFieldHandlers, this._log); if (fieldPayloads && fieldPayloads.length) { fieldPayloads.forEach(function (fieldPayload) { var handler = _this._handlerProvider && _this._handlerProvider(fieldPayload.handle); !handler ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected a handler to be provided for ' + 'handle `%s`.', fieldPayload.handle) : invariant(false) : void 0; handler.update(recordSourceProxy, fieldPayload); }); } if (updater) { var selector = operation.fragment; !(selector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernEnvironment: Expected a selector to be provided with updater function.') : invariant(false) : void 0; var recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(mutator, recordSourceProxy, selector, this._missingFieldHandlers); var selectorData = lookupSelector(source, selector); updater(recordSourceSelectorProxy, selectorData); } var idsMarkedForInvalidation = recordSourceProxy.getIDsMarkedForInvalidation(); this._store.publish(source, idsMarkedForInvalidation); return recordSourceProxy.isStoreMarkedForInvalidation(); }; _proto._commitData = function _commitData() { var _this2 = this; if (!this._pendingData.size) { return false; } var invalidatedStore = false; this._pendingData.forEach(function (data) { if (data.kind === 'payload') { var payloadInvalidatedStore = _this2._publishSourceFromPayload(data); invalidatedStore = invalidatedStore || payloadInvalidatedStore; } else if (data.kind === 'source') { var source = data.source; _this2._store.publish(source); } else { var updater = data.updater; var sink = RelayRecordSource.create(); var mutator = new RelayRecordSourceMutator(_this2._store.getSource(), sink); var recordSourceProxy = new RelayRecordSourceProxy(mutator, _this2._getDataID, _this2._handlerProvider, _this2._missingFieldHandlers, _this2._log); applyWithGuard(updater, null, [recordSourceProxy], null, 'RelayPublishQueue:commitData'); invalidatedStore = invalidatedStore || recordSourceProxy.isStoreMarkedForInvalidation(); var idsMarkedForInvalidation = recordSourceProxy.getIDsMarkedForInvalidation(); _this2._store.publish(sink, idsMarkedForInvalidation); } }); this._pendingData.clear(); return invalidatedStore; }; _proto._applyUpdates = function _applyUpdates() { var _this3 = this; var sink = RelayRecordSource.create(); var mutator = new RelayRecordSourceMutator(this._store.getSource(), sink); var recordSourceProxy = new RelayRecordSourceProxy(mutator, this._getDataID, this._handlerProvider, this._missingFieldHandlers, this._log); var processUpdate = function processUpdate(optimisticUpdate) { if (optimisticUpdate.storeUpdater) { var storeUpdater = optimisticUpdate.storeUpdater; applyWithGuard(storeUpdater, null, [recordSourceProxy], null, 'RelayPublishQueue:applyUpdates'); } else { var operation = optimisticUpdate.operation, payload = optimisticUpdate.payload, updater = optimisticUpdate.updater; var source = payload.source, fieldPayloads = payload.fieldPayloads; if (source) { recordSourceProxy.publishSource(source, fieldPayloads); } if (updater) { var selectorData; if (source) { selectorData = lookupSelector(source, operation.fragment); } var recordSourceSelectorProxy = new RelayRecordSourceSelectorProxy(mutator, recordSourceProxy, operation.fragment, _this3._missingFieldHandlers); applyWithGuard(updater, null, [recordSourceSelectorProxy, selectorData], null, 'RelayPublishQueue:applyUpdates'); } } }; if (this._pendingBackupRebase && this._appliedOptimisticUpdates.size) { this._appliedOptimisticUpdates.forEach(processUpdate); } if (this._pendingOptimisticUpdates.size) { this._pendingOptimisticUpdates.forEach(function (optimisticUpdate) { processUpdate(optimisticUpdate); _this3._appliedOptimisticUpdates.add(optimisticUpdate); }); this._pendingOptimisticUpdates.clear(); } this._store.publish(sink); }; return RelayPublishQueue; }(); function lookupSelector(source, selector) { var selectorData = RelayReader.read(source, selector).data; if (process.env.NODE_ENV !== "production") { var deepFreeze = require('../util/deepFreeze'); if (selectorData) { deepFreeze(selectorData); } } return selectorData; } module.exports = RelayPublishQueue;