/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * strict-local * @format */ 'use strict'; function mark(recordSource, selector, references, operationLoader) { var dataID = selector.dataID, node = selector.node, variables = selector.variables; var marker = new RelayReferenceMarker(recordSource, variables, references, operationLoader); marker.mark(node, dataID); } /** * @private */ var RelayReferenceMarker = /*#__PURE__*/ function () { function RelayReferenceMarker(recordSource, variables, references, operationLoader) { var _operationLoader; this._operationLoader = (_operationLoader = operationLoader) !== null && _operationLoader !== void 0 ? _operationLoader : null; this._references = references; this._recordSource = recordSource; this._variables = variables; } var _proto = RelayReferenceMarker.prototype; _proto.mark = function mark(node, dataID) { this._traverse(node, dataID); }; _proto._traverse = function _traverse(node, dataID) { this._references.add(dataID); var record = this._recordSource.get(dataID); if (record == null) { return; } this._traverseSelections(node.selections, record); }; _proto._getVariableValue = function _getVariableValue(name) { !this._variables.hasOwnProperty(name) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayReferenceMarker(): Undefined variable `%s`.', name) : require("fbjs/lib/invariant")(false) : void 0; return this._variables[name]; }; _proto._traverseSelections = function _traverseSelections(selections, record) { var _this = this; selections.forEach(function (selection) { /* eslint-disable no-fallthrough */ switch (selection.kind) { case require("./RelayConcreteNode").LINKED_FIELD: if (selection.plural) { _this._traversePluralLink(selection, record); } else { _this._traverseLink(selection, record); } break; case require("./RelayConcreteNode").CONDITION: var conditionValue = _this._getVariableValue(selection.condition); if (conditionValue === selection.passingValue) { _this._traverseSelections(selection.selections, record); } break; case require("./RelayConcreteNode").INLINE_FRAGMENT: var typeName = require("./RelayModernRecord").getType(record); if (typeName != null && typeName === selection.type) { _this._traverseSelections(selection.selections, record); } break; case require("./RelayConcreteNode").FRAGMENT_SPREAD: !false ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayReferenceMarker(): Unexpected fragment spread `...%s`, ' + 'expected all fragments to be inlined.', selection.name) : require("fbjs/lib/invariant")(false) : void 0; case require("./RelayConcreteNode").LINKED_HANDLE: // The selections for a "handle" field are the same as those of the // original linked field where the handle was applied. Reference marking // therefore requires traversing the original field selections against // the synthesized client field. // // TODO: Instead of finding the source field in `selections`, change // the concrete structure to allow shared subtrees, and have the linked // handle directly refer to the same selections as the LinkedField that // it was split from. var handleField = require("./cloneRelayHandleSourceField")(selection, selections, _this._variables); if (handleField.plural) { _this._traversePluralLink(handleField, record); } else { _this._traverseLink(handleField, record); } break; case require("./RelayConcreteNode").DEFER: case require("./RelayConcreteNode").STREAM: _this._traverseSelections(selection.selections, record); break; case require("./RelayConcreteNode").SCALAR_FIELD: case require("./RelayConcreteNode").SCALAR_HANDLE: break; case require("./RelayConcreteNode").MATCH_FIELD: _this._traverseMatch(selection, record); break; default: selection; !false ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayReferenceMarker: Unknown AST node `%s`.', selection) : require("fbjs/lib/invariant")(false) : void 0; } }); }; _proto._traverseMatch = function _traverseMatch(field, record) { var storageKey = require("./RelayStoreUtils").getStorageKey(field, this._variables); var linkedID = require("./RelayModernRecord").getLinkedRecordID(record, storageKey); if (linkedID == null) { return; } this._references.add(linkedID); var linkedRecord = this._recordSource.get(linkedID); if (linkedRecord == null) { return; } var typeName = require("./RelayModernRecord").getType(linkedRecord); var match = field.matchesByType[typeName]; if (match != null) { var operationLoader = this._operationLoader; !(operationLoader !== null) ? process.env.NODE_ENV !== "production" ? require("fbjs/lib/invariant")(false, 'RelayReferenceMarker: Expected an operationLoader to be configured when using `@match`.') : require("fbjs/lib/invariant")(false) : void 0; var operationReference = require("./RelayModernRecord").getValue(linkedRecord, require("./RelayStoreUtils").MATCH_FRAGMENT_KEY); if (operationReference == null) { return; } var operation = operationLoader.get(operationReference); if (operation != null) { this._traverseSelections(operation.selections, linkedRecord); } // If the operation is not available, we assume that the data cannot have been // processed yet and therefore isn't in the store to begin with. } else {// TODO: warn: store is corrupt: the field should be null if the typename did not match } }; _proto._traverseLink = function _traverseLink(field, record) { var storageKey = require("./RelayStoreUtils").getStorageKey(field, this._variables); var linkedID = require("./RelayModernRecord").getLinkedRecordID(record, storageKey); if (linkedID == null) { return; } this._traverse(field, linkedID); }; _proto._traversePluralLink = function _traversePluralLink(field, record) { var _this2 = this; var storageKey = require("./RelayStoreUtils").getStorageKey(field, this._variables); var linkedIDs = require("./RelayModernRecord").getLinkedRecordIDs(record, storageKey); if (linkedIDs == null) { return; } linkedIDs.forEach(function (linkedID) { if (linkedID != null) { _this2._traverse(field, linkedID); } }); }; return RelayReferenceMarker; }(); module.exports = { mark: mark };