relay-runtime 0.0.0-main-1fcce07e → 0.0.0-main-40a2fce7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/experimental.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v0.0.0-main-1fcce07e
2
+ * Relay v0.0.0-main-40a2fce7
3
3
  *
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Relay v0.0.0-main-1fcce07e
2
+ * Relay v0.0.0-main-40a2fce7
3
3
  *
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
@@ -629,69 +629,90 @@ var RelayReader = /*#__PURE__*/function () {
629
629
  }
630
630
  if (field.linkedField.plural) {
631
631
  !Array.isArray(clientEdgeResolverResponse) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected plural Client Edge Relay Resolver at `%s` in `%s` to return an array containing IDs or objects with shape {id}.', backingField.path, this._owner.identifier) : invariant(false) : void 0;
632
- var storeIDs;
633
632
  !(field.kind === 'ClientEdgeToClientObject') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Unexpected Client Edge to plural server type `%s`. This should be prevented by the compiler.', field.kind) : invariant(false) : void 0;
633
+ var storeIDs;
634
+ var perItemEdges;
634
635
  if (field.backingField.normalizationInfo == null) {
635
- storeIDs = clientEdgeResolverResponse.map(function (itemResponse) {
636
+ storeIDs = [];
637
+ perItemEdges = [];
638
+ for (var i = 0; i < clientEdgeResolverResponse.length; i++) {
636
639
  var _field$concreteType;
640
+ var itemResponse = clientEdgeResolverResponse[i];
637
641
  if (itemResponse == null) {
638
- return null;
642
+ storeIDs.push(null);
643
+ perItemEdges.push(null);
644
+ continue;
639
645
  }
640
646
  var concreteType = (_field$concreteType = field.concreteType) !== null && _field$concreteType !== void 0 ? _field$concreteType : itemResponse.__typename;
641
- !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, _this3._owner.identifier) : invariant(false) : void 0;
642
- var localId = extractIdFromResponse(itemResponse, backingField.path, _this3._owner.identifier);
647
+ !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, this._owner.identifier) : invariant(false) : void 0;
648
+ var localId = extractIdFromResponse(itemResponse, backingField.path, this._owner.identifier);
643
649
  var modelResolvers = field.modelResolvers;
644
650
  if (modelResolvers != null) {
645
651
  var modelResolver = modelResolvers[concreteType];
646
652
  if (modelResolver !== undefined) {
647
- var _id = _this3._resolverCache.ensureClientRecord(localId, concreteType);
648
- var model = _this3._readResolverFieldImpl(modelResolver, _id);
649
- return model != null ? _id : null;
653
+ var id = this._resolverCache.ensureClientRecord(localId, concreteType);
654
+ var model = this._readResolverFieldImpl(modelResolver, id);
655
+ storeIDs.push(model != null ? id : null);
656
+ perItemEdges.push(null);
650
657
  } else {
651
- return localId;
658
+ var _field$serverObjectOp, _field$serverObjectOp2;
659
+ storeIDs.push(localId);
660
+ var serverOperation = (_field$serverObjectOp = (_field$serverObjectOp2 = field.serverObjectOperations) === null || _field$serverObjectOp2 === void 0 ? void 0 : _field$serverObjectOp2[concreteType]) !== null && _field$serverObjectOp !== void 0 ? _field$serverObjectOp : null;
661
+ if (serverOperation != null) {
662
+ perItemEdges.push({
663
+ clientEdgeDestinationID: localId,
664
+ readerClientEdge: {
665
+ operation: serverOperation
666
+ }
667
+ });
668
+ } else {
669
+ perItemEdges.push(null);
670
+ }
652
671
  }
672
+ } else {
673
+ storeIDs.push(this._resolverCache.ensureClientRecord(localId, concreteType));
674
+ perItemEdges.push(null);
653
675
  }
654
- var id = _this3._resolverCache.ensureClientRecord(localId, concreteType);
655
- return id;
656
- });
676
+ }
657
677
  } else {
658
678
  storeIDs = clientEdgeResolverResponse.map(function (obj) {
659
679
  return extractIdFromResponse(obj, backingField.path, _this3._owner.identifier);
660
680
  });
681
+ perItemEdges = null;
661
682
  }
662
683
  var prevParentClientEdge = this._parentClientEdge;
663
684
  this._parentClientEdge = null;
664
- var edgeValues = this._readLinkedIds(field.linkedField, storeIDs, record, data);
685
+ var edgeValues = this._readLinkedIds(field.linkedField, storeIDs, record, data, perItemEdges);
665
686
  this._parentClientEdge = prevParentClientEdge;
666
687
  data[fieldName] = edgeValues;
667
688
  return edgeValues;
668
689
  } else {
669
690
  var _field$concreteType2;
670
- var id = extractIdFromResponse(clientEdgeResolverResponse, backingField.path, this._owner.identifier);
691
+ var _id = extractIdFromResponse(clientEdgeResolverResponse, backingField.path, this._owner.identifier);
671
692
  var storeID;
672
- var concreteType = (_field$concreteType2 = field.concreteType) !== null && _field$concreteType2 !== void 0 ? _field$concreteType2 : clientEdgeResolverResponse.__typename;
693
+ var _concreteType = (_field$concreteType2 = field.concreteType) !== null && _field$concreteType2 !== void 0 ? _field$concreteType2 : clientEdgeResolverResponse.__typename;
673
694
  var traversalPathSegment;
674
695
  if (field.kind === 'ClientEdgeToClientObject') {
675
696
  if (field.backingField.normalizationInfo == null) {
676
- !(typeof concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, this._owner.identifier) : invariant(false) : void 0;
677
- var modelResolvers = field.modelResolvers;
678
- if (modelResolvers != null) {
679
- var modelResolver = modelResolvers[concreteType];
680
- if (modelResolver !== undefined) {
681
- storeID = this._resolverCache.ensureClientRecord(id, concreteType);
682
- var model = this._readResolverFieldImpl(modelResolver, storeID);
683
- if (model == null) {
697
+ !(typeof _concreteType === 'string') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Expected resolver for field at `%s` in `%s` modeling an edge to an abstract type to return an object with a `__typename` property.', backingField.path, this._owner.identifier) : invariant(false) : void 0;
698
+ var _modelResolvers = field.modelResolvers;
699
+ if (_modelResolvers != null) {
700
+ var _modelResolver = _modelResolvers[_concreteType];
701
+ if (_modelResolver !== undefined) {
702
+ storeID = this._resolverCache.ensureClientRecord(_id, _concreteType);
703
+ var _model = this._readResolverFieldImpl(_modelResolver, storeID);
704
+ if (_model == null) {
684
705
  data[fieldName] = null;
685
706
  return null;
686
707
  }
687
708
  traversalPathSegment = null;
688
709
  } else {
689
- storeID = id;
710
+ storeID = _id;
690
711
  var serverObjectOperations = field.serverObjectOperations;
691
- var serverOp = serverObjectOperations != null ? serverObjectOperations[concreteType] : null;
712
+ var serverOp = serverObjectOperations != null ? serverObjectOperations[_concreteType] : null;
692
713
  if (serverOp != null) {
693
714
  traversalPathSegment = {
694
- clientEdgeDestinationID: id,
715
+ clientEdgeDestinationID: _id,
695
716
  readerClientEdge: {
696
717
  operation: serverOp
697
718
  }
@@ -701,17 +722,17 @@ var RelayReader = /*#__PURE__*/function () {
701
722
  }
702
723
  }
703
724
  } else {
704
- storeID = this._resolverCache.ensureClientRecord(id, concreteType);
725
+ storeID = this._resolverCache.ensureClientRecord(_id, _concreteType);
705
726
  traversalPathSegment = null;
706
727
  }
707
728
  } else {
708
- storeID = id;
729
+ storeID = _id;
709
730
  traversalPathSegment = null;
710
731
  }
711
732
  } else {
712
- storeID = id;
733
+ storeID = _id;
713
734
  traversalPathSegment = {
714
- clientEdgeDestinationID: id,
735
+ clientEdgeDestinationID: _id,
715
736
  readerClientEdge: field
716
737
  };
717
738
  }
@@ -825,7 +846,7 @@ var RelayReader = /*#__PURE__*/function () {
825
846
  }
826
847
  return this._readLinkedIds(field, linkedIDs, record, data);
827
848
  };
828
- _proto._readLinkedIds = function _readLinkedIds(field, linkedIDs, record, data) {
849
+ _proto._readLinkedIds = function _readLinkedIds(field, linkedIDs, record, data, perItemEdges) {
829
850
  var _this4 = this;
830
851
  var _field$alias6;
831
852
  var fieldName = (_field$alias6 = field.alias) !== null && _field$alias6 !== void 0 ? _field$alias6 : field.name;
@@ -853,7 +874,13 @@ var RelayReader = /*#__PURE__*/function () {
853
874
  !(prevItem == null || typeof prevItem === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field `%s` on record `%s` ' + 'to be an object, got `%s`.', fieldName, RelayModernRecord.getDataID(record), prevItem) : invariant(false) : void 0;
854
875
  var prevErrors = _this4._fieldErrors;
855
876
  _this4._fieldErrors = null;
877
+ var prevParentClientEdge = _this4._parentClientEdge;
878
+ if (perItemEdges != null) {
879
+ var _perItemEdges$nextInd;
880
+ _this4._parentClientEdge = (_perItemEdges$nextInd = perItemEdges[nextIndex]) !== null && _perItemEdges$nextInd !== void 0 ? _perItemEdges$nextInd : null;
881
+ }
856
882
  linkedArray[nextIndex] = _this4._traverse(field, linkedID, prevItem);
883
+ _this4._parentClientEdge = prevParentClientEdge;
857
884
  _this4._prependPreviousErrors(prevErrors, nextIndex);
858
885
  });
859
886
  this._prependPreviousErrors(prevErrors, fieldName);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "relay-runtime",
3
3
  "description": "A core runtime for building GraphQL-driven applications.",
4
- "version": "0.0.0-main-1fcce07e",
4
+ "version": "0.0.0-main-40a2fce7",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"
@@ -1073,20 +1073,28 @@ class RelayReader {
1073
1073
  backingField.path,
1074
1074
  this._owner.identifier,
1075
1075
  );
1076
- let storeIDs: ReadonlyArray<DataID>;
1077
1076
  invariant(
1078
1077
  field.kind === 'ClientEdgeToClientObject',
1079
1078
  'Unexpected Client Edge to plural server type `%s`. This should be prevented by the compiler.',
1080
1079
  field.kind,
1081
1080
  );
1081
+ let storeIDs: Array<?DataID>;
1082
+ let perItemEdges: ?Array<ClientEdgeTraversalInfo | null>;
1082
1083
  if (field.backingField.normalizationInfo == null) {
1083
- // @edgeTo case where we need to ensure that the record has `id` field
1084
- storeIDs = clientEdgeResolverResponse.map(itemResponse => {
1084
+ // @edgeTo case: compute storeIDs and per-item traversal segments.
1085
+ // Server-type items get a segment so that missing data in their
1086
+ // sub-tree triggers a waterfall refetch; all other items get null.
1087
+ storeIDs = [];
1088
+ perItemEdges = [];
1089
+ for (let i = 0; i < clientEdgeResolverResponse.length; i++) {
1090
+ const itemResponse = clientEdgeResolverResponse[i];
1085
1091
  // A plural resolver (e.g. a plural magic fragment) may return a list
1086
1092
  // with nullish items — a nullable list element. Read those through as a
1087
1093
  // null edge rather than dereferencing `__typename` on a nullish value.
1088
1094
  if (itemResponse == null) {
1089
- return null;
1095
+ storeIDs.push(null);
1096
+ perItemEdges.push(null);
1097
+ continue;
1090
1098
  }
1091
1099
  const concreteType = field.concreteType ?? itemResponse.__typename;
1092
1100
  invariant(
@@ -1100,7 +1108,6 @@ class RelayReader {
1100
1108
  backingField.path,
1101
1109
  this._owner.identifier,
1102
1110
  );
1103
-
1104
1111
  const modelResolvers = field.modelResolvers;
1105
1112
  if (modelResolvers != null) {
1106
1113
  const modelResolver = modelResolvers[concreteType];
@@ -1111,24 +1118,39 @@ class RelayReader {
1111
1118
  concreteType,
1112
1119
  );
1113
1120
  const model = this._readResolverFieldImpl(modelResolver, id);
1114
- return model != null ? id : null;
1121
+ storeIDs.push(model != null ? id : null);
1122
+ perItemEdges.push(null);
1115
1123
  } else {
1116
- // Server/CSE type: use the original ID directly.
1117
- return localId;
1124
+ storeIDs.push(localId);
1125
+
1126
+ // Server/CLient Schema Extension type: check for a refetch operation so that
1127
+ // missing data in this item's sub-tree triggers a waterfall.
1128
+ const serverOperation =
1129
+ field.serverObjectOperations?.[concreteType] ?? null;
1130
+ if (serverOperation != null) {
1131
+ perItemEdges.push({
1132
+ clientEdgeDestinationID: localId,
1133
+ readerClientEdge: {operation: serverOperation},
1134
+ });
1135
+ } else {
1136
+ perItemEdges.push(null);
1137
+ }
1118
1138
  }
1139
+ } else {
1140
+ // No model resolvers — concrete client object edge.
1141
+ storeIDs.push(
1142
+ this._resolverCache.ensureClientRecord(localId, concreteType),
1143
+ );
1144
+ perItemEdges.push(null);
1119
1145
  }
1120
- // No model resolvers — concrete client object edge.
1121
- const id = this._resolverCache.ensureClientRecord(
1122
- localId,
1123
- concreteType,
1124
- );
1125
- return id;
1126
- });
1146
+ }
1127
1147
  } else {
1128
- // The normalization process in LiveResolverCache should take care of generating the correct ID.
1148
+ // The normalization process in LiveResolverCache should take care of
1149
+ // generating the correct ID.
1129
1150
  storeIDs = clientEdgeResolverResponse.map(obj =>
1130
1151
  extractIdFromResponse(obj, backingField.path, this._owner.identifier),
1131
1152
  );
1153
+ perItemEdges = null;
1132
1154
  }
1133
1155
  const prevParentClientEdge = this._parentClientEdge;
1134
1156
  this._parentClientEdge = null;
@@ -1137,6 +1159,7 @@ class RelayReader {
1137
1159
  storeIDs,
1138
1160
  record,
1139
1161
  data,
1162
+ perItemEdges,
1140
1163
  );
1141
1164
  this._parentClientEdge = prevParentClientEdge;
1142
1165
  data[fieldName] = edgeValues;
@@ -1447,6 +1470,7 @@ class RelayReader {
1447
1470
  linkedIDs: ?ReadonlyArray<?DataID>,
1448
1471
  record: Record,
1449
1472
  data: SelectorData,
1473
+ perItemEdges?: ?ReadonlyArray<ClientEdgeTraversalInfo | null>,
1450
1474
  ): ?unknown {
1451
1475
  const fieldName = field.alias ?? field.name;
1452
1476
 
@@ -1490,9 +1514,14 @@ class RelayReader {
1490
1514
  );
1491
1515
  const prevErrors = this._fieldErrors;
1492
1516
  this._fieldErrors = null;
1517
+ const prevParentClientEdge = this._parentClientEdge;
1518
+ if (perItemEdges != null) {
1519
+ this._parentClientEdge = perItemEdges[nextIndex] ?? null;
1520
+ }
1493
1521
  // $FlowFixMe[cannot-write]
1494
1522
  // $FlowFixMe[incompatible-variance]
1495
1523
  linkedArray[nextIndex] = this._traverse(field, linkedID, prevItem);
1524
+ this._parentClientEdge = prevParentClientEdge;
1496
1525
  this._prependPreviousErrors(prevErrors, nextIndex);
1497
1526
  });
1498
1527
  this._prependPreviousErrors(prevErrors, fieldName);