214 lines
7.0 KiB
JavaScript
214 lines
7.0 KiB
JavaScript
/**
|
|
* 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
|
|
}; |