relay-runtime 0.0.0-main-40e5218d → 0.0.0-main-4ceaefa5

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-40e5218d
2
+ * Relay v0.0.0-main-4ceaefa5
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-40e5218d
2
+ * Relay v0.0.0-main-4ceaefa5
3
3
  *
4
4
  * Copyright (c) Meta Platforms, Inc. and affiliates.
5
5
  *
@@ -3,11 +3,11 @@
3
3
  var _require = require('./RelayConcreteVariables'),
4
4
  getFragmentVariables = _require.getFragmentVariables;
5
5
  var _require2 = require('./RelayStoreUtils'),
6
- CLIENT_EDGE_TRAVERSAL_PATH = _require2.CLIENT_EDGE_TRAVERSAL_PATH,
7
6
  FRAGMENT_OWNER_KEY = _require2.FRAGMENT_OWNER_KEY,
8
7
  FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT = _require2.FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,
9
8
  FRAGMENTS_KEY = _require2.FRAGMENTS_KEY,
10
- ID_KEY = _require2.ID_KEY;
9
+ ID_KEY = _require2.ID_KEY,
10
+ PARENT_CLIENT_EDGE = _require2.PARENT_CLIENT_EDGE;
11
11
  var areEqual = require("fbjs/lib/areEqual");
12
12
  var invariant = require('invariant');
13
13
  var warning = require("fbjs/lib/warning");
@@ -16,14 +16,14 @@ function getSingularSelector(fragment, item) {
16
16
  var dataID = item[ID_KEY];
17
17
  var fragments = item[FRAGMENTS_KEY];
18
18
  var mixedOwner = item[FRAGMENT_OWNER_KEY];
19
- var mixedClientEdgeTraversalPath = item[CLIENT_EDGE_TRAVERSAL_PATH];
20
- if (typeof dataID === 'string' && typeof fragments === 'object' && fragments !== null && typeof fragments[fragment.name] === 'object' && fragments[fragment.name] !== null && typeof mixedOwner === 'object' && mixedOwner !== null && (mixedClientEdgeTraversalPath == null || Array.isArray(mixedClientEdgeTraversalPath))) {
19
+ var mixedParentClientEdge = item[PARENT_CLIENT_EDGE];
20
+ if (typeof dataID === 'string' && typeof fragments === 'object' && fragments !== null && typeof fragments[fragment.name] === 'object' && fragments[fragment.name] !== null && typeof mixedOwner === 'object' && mixedOwner !== null && (mixedParentClientEdge == null || typeof mixedParentClientEdge === 'object')) {
21
21
  var owner = mixedOwner;
22
- var clientEdgeTraversalPath = mixedClientEdgeTraversalPath;
22
+ var parentClientEdge = mixedParentClientEdge;
23
23
  var argumentVariables = fragments[fragment.name];
24
24
  var fragmentVariables = getFragmentVariables(fragment, owner.variables, argumentVariables);
25
25
  var isWithinUnmatchedTypeRefinement = argumentVariables[FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT] === true;
26
- return createReaderSelector(fragment, dataID, fragmentVariables, owner, isWithinUnmatchedTypeRefinement, clientEdgeTraversalPath);
26
+ return createReaderSelector(fragment, dataID, fragmentVariables, owner, isWithinUnmatchedTypeRefinement, parentClientEdge);
27
27
  }
28
28
  if (process.env.NODE_ENV !== "production") {
29
29
  var stringifiedItem = JSON.stringify(item);
@@ -160,7 +160,7 @@ function getVariablesFromPluralFragment(fragment, items) {
160
160
  return variables;
161
161
  }
162
162
  function areEqualSingularSelectors(thisSelector, thatSelector) {
163
- return thisSelector.dataID === thatSelector.dataID && thisSelector.node === thatSelector.node && areEqual(thisSelector.variables, thatSelector.variables) && areEqualOwners(thisSelector.owner, thatSelector.owner) && thisSelector.isWithinUnmatchedTypeRefinement === thatSelector.isWithinUnmatchedTypeRefinement && areEqualClientEdgeTraversalPaths(thisSelector.clientEdgeTraversalPath, thatSelector.clientEdgeTraversalPath);
163
+ return thisSelector.dataID === thatSelector.dataID && thisSelector.node === thatSelector.node && areEqual(thisSelector.variables, thatSelector.variables) && areEqualOwners(thisSelector.owner, thatSelector.owner) && thisSelector.isWithinUnmatchedTypeRefinement === thatSelector.isWithinUnmatchedTypeRefinement && areEqualParentClientEdges(thisSelector.parentClientEdge, thatSelector.parentClientEdge);
164
164
  }
165
165
  function areEqualOwners(thisOwner, thatOwner) {
166
166
  if (thisOwner === thatOwner) {
@@ -169,25 +169,14 @@ function areEqualOwners(thisOwner, thatOwner) {
169
169
  return thisOwner.identifier === thatOwner.identifier && areEqual(thisOwner.cacheConfig, thatOwner.cacheConfig);
170
170
  }
171
171
  }
172
- function areEqualClientEdgeTraversalPaths(thisPath, thatPath) {
173
- if (thisPath === thatPath) {
172
+ function areEqualParentClientEdges(thisEdge, thatEdge) {
173
+ if (thisEdge === thatEdge) {
174
174
  return true;
175
175
  }
176
- if (thisPath == null || thatPath == null || thisPath.length !== thatPath.length) {
176
+ if (thisEdge == null || thatEdge == null) {
177
177
  return false;
178
178
  }
179
- var idx = thisPath.length;
180
- while (idx--) {
181
- var a = thisPath[idx];
182
- var b = thatPath[idx];
183
- if (a === b) {
184
- continue;
185
- }
186
- if (a == null || b == null || a.clientEdgeDestinationID !== b.clientEdgeDestinationID || a.readerClientEdge !== b.readerClientEdge) {
187
- return false;
188
- }
189
- }
190
- return true;
179
+ return thisEdge.clientEdgeDestinationID === thatEdge.clientEdgeDestinationID && thisEdge.readerClientEdge === thatEdge.readerClientEdge;
191
180
  }
192
181
  function areEqualSelectors(a, b) {
193
182
  if (a === b) {
@@ -208,9 +197,9 @@ function areEqualSelectors(a, b) {
208
197
  }
209
198
  function createReaderSelector(fragment, dataID, variables, request) {
210
199
  var isWithinUnmatchedTypeRefinement = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
211
- var clientEdgeTraversalPath = arguments.length > 5 ? arguments[5] : undefined;
200
+ var parentClientEdge = arguments.length > 5 ? arguments[5] : undefined;
212
201
  return {
213
- clientEdgeTraversalPath: clientEdgeTraversalPath !== null && clientEdgeTraversalPath !== void 0 ? clientEdgeTraversalPath : null,
202
+ parentClientEdge: parentClientEdge !== null && parentClientEdge !== void 0 ? parentClientEdge : null,
214
203
  dataID: dataID,
215
204
  isWithinUnmatchedTypeRefinement: isWithinUnmatchedTypeRefinement,
216
205
  kind: 'SingularReaderSelector',
@@ -4,7 +4,6 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
5
5
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
6
6
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
7
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
8
7
  var _excluded = ["message"];
9
8
  var RelayFeatureFlags = require('../util/RelayFeatureFlags');
10
9
  var _require = require('./live-resolvers/LiveResolverSuspenseSentinel'),
@@ -12,13 +11,13 @@ var _require = require('./live-resolvers/LiveResolverSuspenseSentinel'),
12
11
  var RelayConcreteVariables = require('./RelayConcreteVariables');
13
12
  var RelayModernRecord = require('./RelayModernRecord');
14
13
  var _require2 = require('./RelayStoreUtils'),
15
- CLIENT_EDGE_TRAVERSAL_PATH = _require2.CLIENT_EDGE_TRAVERSAL_PATH,
16
14
  FIELD_GRANULAR_NOTIFICATIONS_KEY = _require2.FIELD_GRANULAR_NOTIFICATIONS_KEY,
17
15
  FRAGMENT_OWNER_KEY = _require2.FRAGMENT_OWNER_KEY,
18
16
  FRAGMENT_PROP_NAME_KEY = _require2.FRAGMENT_PROP_NAME_KEY,
19
17
  FRAGMENTS_KEY = _require2.FRAGMENTS_KEY,
20
18
  ID_KEY = _require2.ID_KEY,
21
19
  MODULE_COMPONENT_KEY = _require2.MODULE_COMPONENT_KEY,
20
+ PARENT_CLIENT_EDGE = _require2.PARENT_CLIENT_EDGE,
22
21
  ROOT_ID = _require2.ROOT_ID,
23
22
  getArgumentValues = _require2.getArgumentValues,
24
23
  getFieldNotificationKey = _require2.getFieldNotificationKey,
@@ -38,8 +37,8 @@ function read(recordSource, selector, log, resolverCache, resolverContext) {
38
37
  }
39
38
  var RelayReader = /*#__PURE__*/function () {
40
39
  function RelayReader(recordSource, selector, log, resolverCache, resolverContext) {
41
- var _selector$clientEdgeT, _ref, _this$_owner$node$ope, _this$_owner$node$ope2;
42
- this._clientEdgeTraversalPath = (_selector$clientEdgeT = selector.clientEdgeTraversalPath) !== null && _selector$clientEdgeT !== void 0 && _selector$clientEdgeT.length ? (0, _toConsumableArray2["default"])(selector.clientEdgeTraversalPath) : [];
40
+ var _ref, _this$_owner$node$ope, _this$_owner$node$ope2;
41
+ this._parentClientEdge = selector.parentClientEdge;
43
42
  this._missingClientEdges = [];
44
43
  this._missingLiveResolverFields = [];
45
44
  this._isMissingData = false;
@@ -151,14 +150,11 @@ var RelayReader = /*#__PURE__*/function () {
151
150
  uiContext: undefined
152
151
  });
153
152
  this._isMissingData = true;
154
- if (this._clientEdgeTraversalPath.length) {
155
- var top = this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1];
156
- if (top !== null) {
157
- this._missingClientEdges.push({
158
- clientEdgeDestinationID: top.clientEdgeDestinationID,
159
- request: top.readerClientEdge.operation
160
- });
161
- }
153
+ if (this._parentClientEdge !== null) {
154
+ this._missingClientEdges.push({
155
+ clientEdgeDestinationID: this._parentClientEdge.clientEdgeDestinationID,
156
+ request: this._parentClientEdge.readerClientEdge.operation
157
+ });
162
158
  }
163
159
  };
164
160
  _proto._traverse = function _traverse(node, dataID, prevData) {
@@ -403,10 +399,11 @@ var RelayReader = /*#__PURE__*/function () {
403
399
  {
404
400
  var isMissingData = this._isMissingData;
405
401
  var alreadyMissingClientEdges = this._missingClientEdges.length;
406
- this._clientEdgeTraversalPath.push(null);
402
+ var prevParentClientEdge = this._parentClientEdge;
403
+ this._parentClientEdge = null;
407
404
  var _hasExpectedData2 = this._traverseSelections(selection.selections, record, data);
408
405
  this._isMissingData = isMissingData || this._missingClientEdges.length > alreadyMissingClientEdges || this._missingLiveResolverFields.length > 0;
409
- this._clientEdgeTraversalPath.pop();
406
+ this._parentClientEdge = prevParentClientEdge;
410
407
  if (!_hasExpectedData2) {
411
408
  return false;
412
409
  }
@@ -518,8 +515,8 @@ var RelayReader = /*#__PURE__*/function () {
518
515
  __fragments: (0, _defineProperty2["default"])({}, fragment.name, fragment.args ? getArgumentValues(fragment.args, _this._variables) : {}),
519
516
  __id: parentRecordID
520
517
  };
521
- if (_this._clientEdgeTraversalPath.length > 0 && _this._clientEdgeTraversalPath[_this._clientEdgeTraversalPath.length - 1] !== null) {
522
- key[CLIENT_EDGE_TRAVERSAL_PATH] = (0, _toConsumableArray2["default"])(_this._clientEdgeTraversalPath);
518
+ if (_this._parentClientEdge !== null) {
519
+ key[PARENT_CLIENT_EDGE] = _this._parentClientEdge;
523
520
  }
524
521
  var resolverContext = {
525
522
  getDataForResolverFragment: getDataForResolverFragment
@@ -659,9 +656,10 @@ var RelayReader = /*#__PURE__*/function () {
659
656
  return extractIdFromResponse(obj, backingField.path, _this3._owner.identifier);
660
657
  });
661
658
  }
662
- this._clientEdgeTraversalPath.push(null);
659
+ var prevParentClientEdge = this._parentClientEdge;
660
+ this._parentClientEdge = null;
663
661
  var edgeValues = this._readLinkedIds(field.linkedField, storeIDs, record, data);
664
- this._clientEdgeTraversalPath.pop();
662
+ this._parentClientEdge = prevParentClientEdge;
665
663
  data[fieldName] = edgeValues;
666
664
  return edgeValues;
667
665
  } else {
@@ -714,14 +712,15 @@ var RelayReader = /*#__PURE__*/function () {
714
712
  readerClientEdge: field
715
713
  };
716
714
  }
717
- this._clientEdgeTraversalPath.push(traversalPathSegment);
715
+ var _prevParentClientEdge = this._parentClientEdge;
716
+ this._parentClientEdge = traversalPathSegment;
718
717
  var prevData = data[fieldName];
719
718
  !(prevData == null || typeof prevData === 'object') ? process.env.NODE_ENV !== "production" ? invariant(false, 'RelayReader(): Expected data for field at `%s` in `%s` on record `%s` ' + 'to be an object, got `%s`.', backingField.path, this._owner.identifier, RelayModernRecord.getDataID(record), prevData) : invariant(false) : void 0;
720
719
  var prevErrors = this._fieldErrors;
721
720
  this._fieldErrors = null;
722
721
  var edgeValue = this._traverse(field.linkedField, storeID, prevData);
723
722
  this._prependPreviousErrors(prevErrors, fieldName);
724
- this._clientEdgeTraversalPath.pop();
723
+ this._parentClientEdge = _prevParentClientEdge;
725
724
  data[fieldName] = edgeValue;
726
725
  return edgeValue;
727
726
  }
@@ -942,8 +941,8 @@ var RelayReader = /*#__PURE__*/function () {
942
941
  var args = getArgumentValues(fragmentSpread.args, this._variables, this._isWithinUnmatchedTypeRefinement);
943
942
  fragmentPointers[fragmentSpread.name] = args;
944
943
  data[FRAGMENT_OWNER_KEY] = this._owner;
945
- if (this._clientEdgeTraversalPath.length > 0 && this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1] !== null) {
946
- data[CLIENT_EDGE_TRAVERSAL_PATH] = (0, _toConsumableArray2["default"])(this._clientEdgeTraversalPath);
944
+ if (this._parentClientEdge !== null) {
945
+ data[PARENT_CLIENT_EDGE] = this._parentClientEdge;
947
946
  }
948
947
  if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
949
948
  var _this$_log2;
@@ -132,7 +132,7 @@ function getFieldNotificationKey(dataID, storageKey) {
132
132
  }
133
133
  var RelayStoreUtils = {
134
134
  ACTOR_IDENTIFIER_KEY: '__actorIdentifier',
135
- CLIENT_EDGE_TRAVERSAL_PATH: '__clientEdgeTraversalPath',
135
+ PARENT_CLIENT_EDGE: '__parentClientEdge',
136
136
  FRAGMENTS_KEY: '__fragments',
137
137
  FRAGMENT_OWNER_KEY: '__fragmentOwner',
138
138
  FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT: '$isWithinUnmatchedTypeRefinement',
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-40e5218d",
4
+ "version": "0.0.0-main-4ceaefa5",
5
5
  "keywords": [
6
6
  "graphql",
7
7
  "relay"
@@ -15,7 +15,7 @@ import type {NormalizationSelectableNode} from '../util/NormalizationNode';
15
15
  import type {ReaderFragment} from '../util/ReaderNode';
16
16
  import type {DataID, Variables} from '../util/RelayRuntimeTypes';
17
17
  import type {
18
- ClientEdgeTraversalPath,
18
+ ClientEdgeTraversalInfo,
19
19
  NormalizationSelector,
20
20
  PluralReaderSelector,
21
21
  ReaderSelector,
@@ -25,11 +25,11 @@ import type {
25
25
 
26
26
  const {getFragmentVariables} = require('./RelayConcreteVariables');
27
27
  const {
28
- CLIENT_EDGE_TRAVERSAL_PATH,
29
28
  FRAGMENT_OWNER_KEY,
30
29
  FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,
31
30
  FRAGMENTS_KEY,
32
31
  ID_KEY,
32
+ PARENT_CLIENT_EDGE,
33
33
  } = require('./RelayStoreUtils');
34
34
  const areEqual = require('areEqual');
35
35
  const invariant = require('invariant');
@@ -78,7 +78,7 @@ function getSingularSelector(
78
78
  const dataID = item[ID_KEY];
79
79
  const fragments = item[FRAGMENTS_KEY];
80
80
  const mixedOwner = item[FRAGMENT_OWNER_KEY];
81
- const mixedClientEdgeTraversalPath = item[CLIENT_EDGE_TRAVERSAL_PATH];
81
+ const mixedParentClientEdge = item[PARENT_CLIENT_EDGE];
82
82
  if (
83
83
  typeof dataID === 'string' &&
84
84
  typeof fragments === 'object' &&
@@ -87,12 +87,11 @@ function getSingularSelector(
87
87
  fragments[fragment.name] !== null &&
88
88
  typeof mixedOwner === 'object' &&
89
89
  mixedOwner !== null &&
90
- (mixedClientEdgeTraversalPath == null ||
91
- Array.isArray(mixedClientEdgeTraversalPath))
90
+ (mixedParentClientEdge == null || typeof mixedParentClientEdge === 'object')
92
91
  ) {
93
92
  const owner: RequestDescriptor = mixedOwner as $FlowFixMe;
94
- const clientEdgeTraversalPath: ?ClientEdgeTraversalPath =
95
- mixedClientEdgeTraversalPath as $FlowFixMe;
93
+ const parentClientEdge: ?ClientEdgeTraversalInfo =
94
+ mixedParentClientEdge as $FlowFixMe;
96
95
 
97
96
  const argumentVariables = fragments[fragment.name];
98
97
  const fragmentVariables = getFragmentVariables(
@@ -112,7 +111,7 @@ function getSingularSelector(
112
111
  fragmentVariables,
113
112
  owner,
114
113
  isWithinUnmatchedTypeRefinement,
115
- clientEdgeTraversalPath,
114
+ parentClientEdge,
116
115
  );
117
116
  }
118
117
 
@@ -417,9 +416,9 @@ function areEqualSingularSelectors(
417
416
  areEqualOwners(thisSelector.owner, thatSelector.owner) &&
418
417
  thisSelector.isWithinUnmatchedTypeRefinement ===
419
418
  thatSelector.isWithinUnmatchedTypeRefinement &&
420
- areEqualClientEdgeTraversalPaths(
421
- thisSelector.clientEdgeTraversalPath,
422
- thatSelector.clientEdgeTraversalPath,
419
+ areEqualParentClientEdges(
420
+ thisSelector.parentClientEdge,
421
+ thatSelector.parentClientEdge,
423
422
  )
424
423
  );
425
424
  }
@@ -442,37 +441,20 @@ function areEqualOwners(
442
441
  }
443
442
  }
444
443
 
445
- function areEqualClientEdgeTraversalPaths(
446
- thisPath: ClientEdgeTraversalPath | null,
447
- thatPath: ClientEdgeTraversalPath | null,
444
+ function areEqualParentClientEdges(
445
+ thisEdge: ClientEdgeTraversalInfo | null,
446
+ thatEdge: ClientEdgeTraversalInfo | null,
448
447
  ): boolean {
449
- if (thisPath === thatPath) {
448
+ if (thisEdge === thatEdge) {
450
449
  return true;
451
450
  }
452
- if (
453
- thisPath == null ||
454
- thatPath == null ||
455
- thisPath.length !== thatPath.length
456
- ) {
451
+ if (thisEdge == null || thatEdge == null) {
457
452
  return false;
458
453
  }
459
- let idx = thisPath.length;
460
- while (idx--) {
461
- const a = thisPath[idx];
462
- const b = thatPath[idx];
463
- if (a === b) {
464
- continue;
465
- }
466
- if (
467
- a == null ||
468
- b == null ||
469
- a.clientEdgeDestinationID !== b.clientEdgeDestinationID ||
470
- a.readerClientEdge !== b.readerClientEdge
471
- ) {
472
- return false;
473
- }
474
- }
475
- return true;
454
+ return (
455
+ thisEdge.clientEdgeDestinationID === thatEdge.clientEdgeDestinationID &&
456
+ thisEdge.readerClientEdge === thatEdge.readerClientEdge
457
+ );
476
458
  }
477
459
 
478
460
  /**
@@ -516,10 +498,10 @@ function createReaderSelector(
516
498
  variables: Variables,
517
499
  request: RequestDescriptor,
518
500
  isWithinUnmatchedTypeRefinement: boolean = false,
519
- clientEdgeTraversalPath: ?ClientEdgeTraversalPath,
501
+ parentClientEdge: ?ClientEdgeTraversalInfo,
520
502
  ): SingularReaderSelector {
521
503
  return {
522
- clientEdgeTraversalPath: clientEdgeTraversalPath ?? null,
504
+ parentClientEdge: parentClientEdge ?? null,
523
505
  dataID,
524
506
  isWithinUnmatchedTypeRefinement,
525
507
  kind: 'SingularReaderSelector',
@@ -57,13 +57,13 @@ const {
57
57
  const RelayConcreteVariables = require('./RelayConcreteVariables');
58
58
  const RelayModernRecord = require('./RelayModernRecord');
59
59
  const {
60
- CLIENT_EDGE_TRAVERSAL_PATH,
61
60
  FIELD_GRANULAR_NOTIFICATIONS_KEY,
62
61
  FRAGMENT_OWNER_KEY,
63
62
  FRAGMENT_PROP_NAME_KEY,
64
63
  FRAGMENTS_KEY,
65
64
  ID_KEY,
66
65
  MODULE_COMPONENT_KEY,
66
+ PARENT_CLIENT_EDGE,
67
67
  ROOT_ID,
68
68
  getArgumentValues,
69
69
  getFieldNotificationKey,
@@ -99,7 +99,7 @@ function read(
99
99
  * @private
100
100
  */
101
101
  class RelayReader {
102
- _clientEdgeTraversalPath: Array<ClientEdgeTraversalInfo | null>;
102
+ _parentClientEdge: ClientEdgeTraversalInfo | null;
103
103
  _isMissingData: boolean;
104
104
  _missingClientEdges: Array<MissingClientEdgeRequestInfo>;
105
105
  _missingLiveResolverFields: Array<DataID>;
@@ -133,9 +133,7 @@ class RelayReader {
133
133
  resolverCache: ResolverCache,
134
134
  resolverContext: ?ResolverContext,
135
135
  ) {
136
- this._clientEdgeTraversalPath = selector.clientEdgeTraversalPath?.length
137
- ? [...selector.clientEdgeTraversalPath]
138
- : [];
136
+ this._parentClientEdge = selector.parentClientEdge;
139
137
  this._missingClientEdges = [];
140
138
  this._missingLiveResolverFields = [];
141
139
  this._isMissingData = false;
@@ -295,18 +293,14 @@ class RelayReader {
295
293
 
296
294
  this._isMissingData = true;
297
295
 
298
- if (this._clientEdgeTraversalPath.length) {
299
- const top =
300
- this._clientEdgeTraversalPath[this._clientEdgeTraversalPath.length - 1];
301
- // Top can be null if we've traversed past a client edge into an ordinary
302
- // client extension field; we never want to fetch in response to missing
303
- // data off of a client extension field.
304
- if (top !== null) {
305
- this._missingClientEdges.push({
306
- clientEdgeDestinationID: top.clientEdgeDestinationID,
307
- request: top.readerClientEdge.operation,
308
- });
309
- }
296
+ // _parentClientEdge is null when not inside a fetchable client edge (e.g.
297
+ // inside a client extension field); we never want to fetch in response to
298
+ // missing data off of a client extension field.
299
+ if (this._parentClientEdge !== null) {
300
+ this._missingClientEdges.push({
301
+ clientEdgeDestinationID: this._parentClientEdge.clientEdgeDestinationID,
302
+ request: this._parentClientEdge.readerClientEdge.operation,
303
+ });
310
304
  }
311
305
  }
312
306
 
@@ -685,7 +679,8 @@ class RelayReader {
685
679
  case 'ClientExtension': {
686
680
  const isMissingData = this._isMissingData;
687
681
  const alreadyMissingClientEdges = this._missingClientEdges.length;
688
- this._clientEdgeTraversalPath.push(null);
682
+ const prevParentClientEdge = this._parentClientEdge;
683
+ this._parentClientEdge = null;
689
684
  const hasExpectedData = this._traverseSelections(
690
685
  selection.selections,
691
686
  record,
@@ -698,7 +693,7 @@ class RelayReader {
698
693
  isMissingData ||
699
694
  this._missingClientEdges.length > alreadyMissingClientEdges ||
700
695
  this._missingLiveResolverFields.length > 0;
701
- this._clientEdgeTraversalPath.pop();
696
+ this._parentClientEdge = prevParentClientEdge;
702
697
  if (!hasExpectedData) {
703
698
  return false;
704
699
  }
@@ -882,13 +877,8 @@ class RelayReader {
882
877
  },
883
878
  __id: parentRecordID,
884
879
  };
885
- if (
886
- this._clientEdgeTraversalPath.length > 0 &&
887
- this._clientEdgeTraversalPath[
888
- this._clientEdgeTraversalPath.length - 1
889
- ] !== null
890
- ) {
891
- key[CLIENT_EDGE_TRAVERSAL_PATH] = [...this._clientEdgeTraversalPath];
880
+ if (this._parentClientEdge !== null) {
881
+ key[PARENT_CLIENT_EDGE] = this._parentClientEdge;
892
882
  }
893
883
  const resolverContext = {getDataForResolverFragment};
894
884
  // $FlowFixMe[incompatible-type]
@@ -1134,14 +1124,15 @@ class RelayReader {
1134
1124
  extractIdFromResponse(obj, backingField.path, this._owner.identifier),
1135
1125
  );
1136
1126
  }
1137
- this._clientEdgeTraversalPath.push(null);
1127
+ const prevParentClientEdge = this._parentClientEdge;
1128
+ this._parentClientEdge = null;
1138
1129
  const edgeValues = this._readLinkedIds(
1139
1130
  field.linkedField,
1140
1131
  storeIDs,
1141
1132
  record,
1142
1133
  data,
1143
1134
  );
1144
- this._clientEdgeTraversalPath.pop();
1135
+ this._parentClientEdge = prevParentClientEdge;
1145
1136
  data[fieldName] = edgeValues;
1146
1137
  return edgeValues;
1147
1138
  } else {
@@ -1217,7 +1208,8 @@ class RelayReader {
1217
1208
  readerClientEdge: field,
1218
1209
  };
1219
1210
  }
1220
- this._clientEdgeTraversalPath.push(traversalPathSegment);
1211
+ const prevParentClientEdge = this._parentClientEdge;
1212
+ this._parentClientEdge = traversalPathSegment;
1221
1213
 
1222
1214
  const prevData = data[fieldName];
1223
1215
  invariant(
@@ -1238,7 +1230,7 @@ class RelayReader {
1238
1230
  prevData,
1239
1231
  );
1240
1232
  this._prependPreviousErrors(prevErrors, fieldName);
1241
- this._clientEdgeTraversalPath.pop();
1233
+ this._parentClientEdge = prevParentClientEdge;
1242
1234
  data[fieldName] = edgeValue;
1243
1235
  return edgeValue;
1244
1236
  }
@@ -1719,13 +1711,8 @@ class RelayReader {
1719
1711
  fragmentPointers[fragmentSpread.name] = args;
1720
1712
  data[FRAGMENT_OWNER_KEY] = this._owner;
1721
1713
 
1722
- if (
1723
- this._clientEdgeTraversalPath.length > 0 &&
1724
- this._clientEdgeTraversalPath[
1725
- this._clientEdgeTraversalPath.length - 1
1726
- ] !== null
1727
- ) {
1728
- data[CLIENT_EDGE_TRAVERSAL_PATH] = [...this._clientEdgeTraversalPath];
1714
+ if (this._parentClientEdge !== null) {
1715
+ data[PARENT_CLIENT_EDGE] = this._parentClientEdge;
1729
1716
  }
1730
1717
 
1731
1718
  if (RelayFeatureFlags.ENABLE_READER_FRAGMENTS_LOGGING) {
@@ -78,7 +78,7 @@ export type SingularReaderSelector = {
78
78
  readonly kind: 'SingularReaderSelector',
79
79
  readonly dataID: DataID,
80
80
  readonly isWithinUnmatchedTypeRefinement: boolean,
81
- readonly clientEdgeTraversalPath: ClientEdgeTraversalPath | null,
81
+ readonly parentClientEdge: ClientEdgeTraversalInfo | null,
82
82
  readonly node: ReaderFragment,
83
83
  readonly owner: RequestDescriptor,
84
84
  readonly variables: Variables,
@@ -128,9 +128,6 @@ export type ClientEdgeTraversalInfo = {
128
128
  readonly clientEdgeDestinationID: DataID,
129
129
  };
130
130
 
131
- export type ClientEdgeTraversalPath =
132
- ReadonlyArray<ClientEdgeTraversalInfo | null>;
133
-
134
131
  export type MissingClientEdgeRequestInfo = {
135
132
  readonly request: ConcreteRequest,
136
133
  readonly clientEdgeDestinationID: DataID,
@@ -283,7 +283,7 @@ function getFieldNotificationKey(dataID: string, storageKey: string): string {
283
283
  */
284
284
  const RelayStoreUtils = {
285
285
  ACTOR_IDENTIFIER_KEY: '__actorIdentifier',
286
- CLIENT_EDGE_TRAVERSAL_PATH: '__clientEdgeTraversalPath',
286
+ PARENT_CLIENT_EDGE: '__parentClientEdge',
287
287
  FRAGMENTS_KEY: '__fragments',
288
288
  FRAGMENT_OWNER_KEY: '__fragmentOwner',
289
289
  FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT: