Files
30-seconds-of-code/node_modules/relay-runtime/lib/RelayReferenceMarker.js
2019-08-20 15:52:05 +02:00

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
};