relay-runtime
Version:
A core runtime for building GraphQL-driven applications.
326 lines (325 loc) • 15.3 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
var _toPropertyKey2 = _interopRequireDefault(require("@babel/runtime/helpers/toPropertyKey"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var deepFreeze = require('../util/deepFreeze');
var _require = require('./ClientID'),
generateClientObjectClientID = _require.generateClientObjectClientID,
isClientID = _require.isClientID;
var _require2 = require('./live-resolvers/LiveResolverSuspenseSentinel'),
isSuspenseSentinel = _require2.isSuspenseSentinel;
var _require3 = require('./RelayStoreUtils'),
ACTOR_IDENTIFIER_KEY = _require3.ACTOR_IDENTIFIER_KEY,
ERRORS_KEY = _require3.ERRORS_KEY,
ID_KEY = _require3.ID_KEY,
INVALIDATED_AT_KEY = _require3.INVALIDATED_AT_KEY,
REF_KEY = _require3.REF_KEY,
REFS_KEY = _require3.REFS_KEY,
RELAY_RESOLVER_VALUE_KEY = _require3.RELAY_RESOLVER_VALUE_KEY,
ROOT_ID = _require3.ROOT_ID,
TYPENAME_KEY = _require3.TYPENAME_KEY;
var areEqual = require("fbjs/lib/areEqual");
var invariant = require('invariant');
var warning = require("fbjs/lib/warning");
function clone(record) {
return (0, _objectSpread2["default"])({}, record);
}
function copyFields(source, sink) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
if (key !== ID_KEY && key !== TYPENAME_KEY) {
sink[key] = source[key];
}
}
}
}
function create(dataID, typeName) {
var record = {};
record[ID_KEY] = dataID;
record[TYPENAME_KEY] = typeName;
return record;
}
function fromObject(json) {
return json;
}
function getDataID(record) {
return record[ID_KEY];
}
function getFields(record) {
if (ERRORS_KEY in record) {
return Object.keys(record).filter(function (field) {
return field !== ERRORS_KEY;
});
}
return Object.keys(record);
}
function getType(record) {
return record[TYPENAME_KEY];
}
function getErrors(record, storageKey) {
var _record$ERRORS_KEY;
return (_record$ERRORS_KEY = record[ERRORS_KEY]) === null || _record$ERRORS_KEY === void 0 ? void 0 : _record$ERRORS_KEY[storageKey];
}
function getValue(record, storageKey) {
var value = record[storageKey];
if (value && typeof value === 'object') {
!(!value.hasOwnProperty(REF_KEY) && !value.hasOwnProperty(REFS_KEY)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getValue(): Expected a scalar (non-link) value for `%s.%s` ' + 'but found %s.', record[ID_KEY], storageKey, value.hasOwnProperty(REF_KEY) ? 'a linked record' : 'plural linked records') : invariant(false) : void 0;
}
return value;
}
function hasValue(record, storageKey) {
return storageKey in record;
}
function getLinkedRecordID(record, storageKey) {
var maybeLink = record[storageKey];
if (maybeLink == null) {
return maybeLink;
}
var link = maybeLink;
!(typeof link === 'object' && link && typeof link[REF_KEY] === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getLinkedRecordID(): Expected `%s.%s` to be a linked ID, ' + 'was `%s`.%s', record[ID_KEY], storageKey, JSON.stringify(link), typeof link === 'object' && link[REFS_KEY] !== undefined ? ' It appears to be a plural linked record: did you mean to call ' + 'getLinkedRecords() instead of getLinkedRecord()?' : '') : invariant(false) : void 0;
return link[REF_KEY];
}
function hasLinkedRecordID(record, storageKey) {
var maybeLink = record[storageKey];
if (maybeLink == null) {
return false;
}
var link = maybeLink;
return typeof link === 'object' && link && typeof link[REF_KEY] === 'string';
}
function getLinkedRecordIDs(record, storageKey) {
var links = record[storageKey];
if (links == null) {
return links;
}
!(typeof links === 'object' && Array.isArray(links[REFS_KEY])) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getLinkedRecordIDs(): Expected `%s.%s` to contain an array ' + 'of linked IDs, got `%s`.%s', record[ID_KEY], storageKey, JSON.stringify(links), typeof links === 'object' && links[REF_KEY] !== undefined ? ' It appears to be a singular linked record: did you mean to call ' + 'getLinkedRecord() instead of getLinkedRecords()?' : '') : invariant(false) : void 0;
return links[REFS_KEY];
}
function hasLinkedRecordIDs(record, storageKey) {
var links = record[storageKey];
if (links == null) {
return false;
}
return typeof links === 'object' && Array.isArray(links[REFS_KEY]) && links[REFS_KEY].every(function (link) {
return typeof link === 'string';
});
}
function getInvalidationEpoch(record) {
if (record == null) {
return null;
}
var invalidatedAt = record[INVALIDATED_AT_KEY];
if (typeof invalidatedAt !== 'number') {
return null;
}
return invalidatedAt;
}
function update(prevRecord, nextRecord) {
var _updated2;
if (process.env.NODE_ENV !== "production") {
var _getType, _getType2;
var prevID = getDataID(prevRecord);
var nextID = getDataID(nextRecord);
process.env.NODE_ENV !== "production" ? warning(prevID === nextID, 'RelayModernRecord: Invalid record update, expected both versions of ' + 'the record to have the same id, got `%s` and `%s`.', prevID, nextID) : void 0;
var prevType = (_getType = getType(prevRecord)) !== null && _getType !== void 0 ? _getType : null;
var nextType = (_getType2 = getType(nextRecord)) !== null && _getType2 !== void 0 ? _getType2 : null;
process.env.NODE_ENV !== "production" ? warning(isClientID(nextID) && nextID !== ROOT_ID || prevType === nextType, 'RelayModernRecord: Invalid record update, expected both versions of ' + 'record `%s` to have the same `%s` but got conflicting types `%s` ' + 'and `%s`. The GraphQL server likely violated the globally unique ' + 'id requirement by returning the same id for different objects.', prevID, TYPENAME_KEY, prevType, nextType) : void 0;
}
var prevErrorsByKey = prevRecord[ERRORS_KEY];
var nextErrorsByKey = nextRecord[ERRORS_KEY];
var updated = null;
if (prevErrorsByKey == null && nextErrorsByKey == null) {
var _updated;
for (var storageKey in nextRecord) {
if (updated || !areEqual(prevRecord[storageKey], nextRecord[storageKey])) {
updated = updated !== null ? updated : (0, _objectSpread2["default"])({}, prevRecord);
updated[storageKey] = nextRecord[storageKey];
}
}
return (_updated = updated) !== null && _updated !== void 0 ? _updated : prevRecord;
}
for (var _storageKey2 in nextRecord) {
if (_storageKey2 === ERRORS_KEY) {
continue;
}
var nextValue = nextRecord[_storageKey2];
var nextErrors = nextErrorsByKey === null || nextErrorsByKey === void 0 ? void 0 : nextErrorsByKey[_storageKey2];
if (updated == null) {
var prevValue = prevRecord[_storageKey2];
var prevErrors = prevErrorsByKey === null || prevErrorsByKey === void 0 ? void 0 : prevErrorsByKey[_storageKey2];
if (areEqual(prevValue, nextValue) && areEqual(prevErrors, nextErrors)) {
continue;
}
updated = (0, _objectSpread2["default"])({}, prevRecord);
if (prevErrorsByKey != null) {
updated[ERRORS_KEY] = (0, _objectSpread2["default"])({}, prevErrorsByKey);
}
}
setValue(updated, _storageKey2, nextValue);
setErrors(updated, _storageKey2, nextErrors);
}
return (_updated2 = updated) !== null && _updated2 !== void 0 ? _updated2 : prevRecord;
}
function merge(record1, record2) {
if (process.env.NODE_ENV !== "production") {
var _getType3, _getType4;
var prevID = getDataID(record1);
var nextID = getDataID(record2);
process.env.NODE_ENV !== "production" ? warning(prevID === nextID, 'RelayModernRecord: Invalid record merge, expected both versions of ' + 'the record to have the same id, got `%s` and `%s`.', prevID, nextID) : void 0;
var prevType = (_getType3 = getType(record1)) !== null && _getType3 !== void 0 ? _getType3 : null;
var nextType = (_getType4 = getType(record2)) !== null && _getType4 !== void 0 ? _getType4 : null;
process.env.NODE_ENV !== "production" ? warning(isClientID(nextID) && nextID !== ROOT_ID || prevType === nextType, 'RelayModernRecord: Invalid record merge, expected both versions of ' + 'record `%s` to have the same `%s` but got conflicting types `%s` ' + 'and `%s`. The GraphQL server likely violated the globally unique ' + 'id requirement by returning the same id for different objects.', prevID, TYPENAME_KEY, prevType, nextType) : void 0;
}
if (ERRORS_KEY in record1 || ERRORS_KEY in record2) {
var errors1 = record1[ERRORS_KEY],
fields1 = (0, _objectWithoutPropertiesLoose2["default"])(record1, [ERRORS_KEY].map(_toPropertyKey2["default"]));
var errors2 = record2[ERRORS_KEY],
fields2 = (0, _objectWithoutPropertiesLoose2["default"])(record2, [ERRORS_KEY].map(_toPropertyKey2["default"]));
var updated = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, fields1), fields2);
if (errors1 == null && errors2 == null) {
return updated;
}
var updatedErrors = {};
for (var storageKey in errors1) {
if (fields2.hasOwnProperty(storageKey)) {
continue;
}
updatedErrors[storageKey] = errors1[storageKey];
}
for (var _storageKey3 in errors2) {
updatedErrors[_storageKey3] = errors2[_storageKey3];
}
for (var _storageKey in updatedErrors) {
updated[ERRORS_KEY] = updatedErrors;
break;
}
return updated;
} else {
return (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, record1), record2);
}
}
function freeze(record) {
deepFreeze(record);
}
function setErrors(record, storageKey, errors) {
if (process.env.NODE_ENV !== "production") {
process.env.NODE_ENV !== "production" ? warning(storageKey in record, 'RelayModernRecord: Invalid error update, `%s` should not be undefined.', storageKey) : void 0;
}
var errorsByStorageKey = record[ERRORS_KEY];
if (errors != null && errors.length > 0) {
if (errorsByStorageKey == null) {
record[ERRORS_KEY] = (0, _defineProperty2["default"])({}, storageKey, errors);
} else {
errorsByStorageKey[storageKey] = errors;
}
} else if (errorsByStorageKey != null) {
if (delete errorsByStorageKey[storageKey]) {
for (var otherStorageKey in errorsByStorageKey) {
if (errorsByStorageKey.hasOwnProperty(otherStorageKey)) {
return;
}
}
delete record[ERRORS_KEY];
}
}
}
function setValue(record, storageKey, value) {
if (process.env.NODE_ENV !== "production") {
var prevID = getDataID(record);
if (storageKey === ID_KEY) {
process.env.NODE_ENV !== "production" ? warning(prevID === value, 'RelayModernRecord: Invalid field update, expected both versions of ' + 'the record to have the same id, got `%s` and `%s`.', prevID, value) : void 0;
} else if (storageKey === TYPENAME_KEY) {
var _getType5;
var prevType = (_getType5 = getType(record)) !== null && _getType5 !== void 0 ? _getType5 : null;
var nextType = value !== null && value !== void 0 ? value : null;
process.env.NODE_ENV !== "production" ? warning(isClientID(getDataID(record)) && getDataID(record) !== ROOT_ID || prevType === nextType, 'RelayModernRecord: Invalid field update, expected both versions of ' + 'record `%s` to have the same `%s` but got conflicting types `%s` ' + 'and `%s`. The GraphQL server likely violated the globally unique ' + 'id requirement by returning the same id for different objects.', prevID, TYPENAME_KEY, prevType, nextType) : void 0;
}
}
record[storageKey] = value;
}
function setLinkedRecordID(record, storageKey, linkedID) {
var link = {};
link[REF_KEY] = linkedID;
record[storageKey] = link;
}
function setLinkedRecordIDs(record, storageKey, linkedIDs) {
var links = {};
links[REFS_KEY] = linkedIDs;
record[storageKey] = links;
}
function setActorLinkedRecordID(record, storageKey, actorIdentifier, linkedID) {
var link = {};
link[REF_KEY] = linkedID;
link[ACTOR_IDENTIFIER_KEY] = actorIdentifier;
record[storageKey] = link;
}
function getActorLinkedRecordID(record, storageKey) {
var link = record[storageKey];
if (link == null) {
return link;
}
!(typeof link === 'object' && typeof link[REF_KEY] === 'string' && link[ACTOR_IDENTIFIER_KEY] != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getActorLinkedRecordID(): Expected `%s.%s` to be an actor specific linked ID, ' + 'was `%s`.', record[ID_KEY], storageKey, JSON.stringify(link)) : invariant(false) : void 0;
return [link[ACTOR_IDENTIFIER_KEY], link[REF_KEY]];
}
function getResolverLinkedRecordID(record, typeName) {
var id = getValue(record, RELAY_RESOLVER_VALUE_KEY);
if (id == null || isSuspenseSentinel(id)) {
return null;
}
if (typeof id === 'object') {
id = id.id;
}
!(typeof id === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getResolverLinkedRecordID(): Expected value to be a linked ID, ' + 'was `%s`.', JSON.stringify(id)) : invariant(false) : void 0;
return generateClientObjectClientID(typeName, id);
}
function getResolverLinkedRecordIDs(record, typeName) {
var resolverValue = getValue(record, RELAY_RESOLVER_VALUE_KEY);
if (resolverValue == null || isSuspenseSentinel(resolverValue)) {
return null;
}
!Array.isArray(resolverValue) ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getResolverLinkedRecordIDs(): Expected value to be an array of linked IDs, ' + 'was `%s`.', JSON.stringify(resolverValue)) : invariant(false) : void 0;
return resolverValue.map(function (id) {
if (id == null) {
return null;
}
if (typeof id === 'object') {
id = id.id;
}
!(typeof id === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayModernRecord.getResolverLinkedRecordIDs(): Expected item within resolver linked field to be a DataID, ' + 'was `%s`.', JSON.stringify(id)) : invariant(false) : void 0;
return generateClientObjectClientID(typeName, id);
});
}
function toJSON(record) {
return record;
}
module.exports = {
clone: clone,
copyFields: copyFields,
create: create,
freeze: freeze,
fromObject: fromObject,
getDataID: getDataID,
getErrors: getErrors,
getFields: getFields,
getInvalidationEpoch: getInvalidationEpoch,
getLinkedRecordID: getLinkedRecordID,
getLinkedRecordIDs: getLinkedRecordIDs,
getType: getType,
getValue: getValue,
hasValue: hasValue,
hasLinkedRecordID: hasLinkedRecordID,
hasLinkedRecordIDs: hasLinkedRecordIDs,
merge: merge,
setErrors: setErrors,
setValue: setValue,
setLinkedRecordID: setLinkedRecordID,
setLinkedRecordIDs: setLinkedRecordIDs,
update: update,
getActorLinkedRecordID: getActorLinkedRecordID,
setActorLinkedRecordID: setActorLinkedRecordID,
getResolverLinkedRecordID: getResolverLinkedRecordID,
getResolverLinkedRecordIDs: getResolverLinkedRecordIDs,
toJSON: toJSON
};
;