react-relay 15.0.0 → 16.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayQueryFetcher.js.flow +1 -5
  3. package/ReactRelayQueryRenderer.js.flow +9 -36
  4. package/ReactRelayTypes.js.flow +1 -0
  5. package/buildReactRelayContainer.js.flow +3 -1
  6. package/hooks.js +1 -1
  7. package/index.js +1 -1
  8. package/legacy.js +1 -1
  9. package/lib/ReactRelayContainerUtils.js +0 -11
  10. package/lib/ReactRelayContext.js +0 -11
  11. package/lib/ReactRelayFragmentContainer.js +6 -78
  12. package/lib/ReactRelayFragmentMockRenderer.js +0 -11
  13. package/lib/ReactRelayLocalQueryRenderer.js +0 -17
  14. package/lib/ReactRelayPaginationContainer.js +5 -208
  15. package/lib/ReactRelayQueryFetcher.js +2 -51
  16. package/lib/ReactRelayQueryRenderer.js +6 -94
  17. package/lib/ReactRelayQueryRendererContext.js +0 -11
  18. package/lib/ReactRelayRefetchContainer.js +5 -91
  19. package/lib/ReactRelayTestMocker.js +9 -85
  20. package/lib/ReactRelayTypes.js +0 -11
  21. package/lib/RelayContext.js +0 -21
  22. package/lib/assertFragmentMap.js +0 -15
  23. package/lib/buildReactRelayContainer.js +0 -19
  24. package/lib/getRootVariablesForFragments.js +0 -14
  25. package/lib/hooks.js +0 -15
  26. package/lib/index.js +0 -17
  27. package/lib/isRelayEnvironment.js +1 -18
  28. package/lib/jest-react/enqueueTask.js +0 -20
  29. package/lib/jest-react/internalAct.js +0 -38
  30. package/lib/legacy.js +0 -15
  31. package/lib/multi-actor/ActorChange.js +0 -11
  32. package/lib/multi-actor/index.js +0 -11
  33. package/lib/multi-actor/useRelayActorEnvironment.js +0 -11
  34. package/lib/relay-hooks/EntryPointContainer.react.js +0 -11
  35. package/lib/relay-hooks/EntryPointTypes.flow.js +1 -14
  36. package/lib/relay-hooks/FragmentResource.js +76 -132
  37. package/lib/relay-hooks/HooksImplementation.js +0 -11
  38. package/lib/relay-hooks/InternalLogger.js +0 -11
  39. package/lib/relay-hooks/LRUCache.js +0 -22
  40. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -18
  41. package/lib/relay-hooks/MatchContainer.js +0 -94
  42. package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
  43. package/lib/relay-hooks/ProfilerContext.js +0 -15
  44. package/lib/relay-hooks/QueryResource.js +2 -68
  45. package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -11
  46. package/lib/relay-hooks/SuspenseResource.js +0 -34
  47. package/lib/relay-hooks/loadEntryPoint.js +1 -24
  48. package/lib/relay-hooks/loadQuery.js +2 -106
  49. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +2 -27
  50. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -13
  51. package/lib/relay-hooks/react-cache/RelayReactCache.js +0 -12
  52. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +1 -36
  53. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +3 -27
  54. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +34 -99
  55. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +0 -15
  56. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +0 -16
  57. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +1 -23
  58. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +0 -29
  59. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +12 -96
  60. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +0 -14
  61. package/lib/relay-hooks/useBlockingPaginationFragment.js +0 -42
  62. package/lib/relay-hooks/useClientQuery.js +0 -18
  63. package/lib/relay-hooks/useEntryPointLoader.js +0 -69
  64. package/lib/relay-hooks/useFetchTrackingRef.js +0 -26
  65. package/lib/relay-hooks/useFragment.js +0 -17
  66. package/lib/relay-hooks/useFragmentNode.js +2 -32
  67. package/lib/relay-hooks/useIsMountedRef.js +0 -11
  68. package/lib/relay-hooks/useIsOperationNodeActive.js +0 -11
  69. package/lib/relay-hooks/useIsParentQueryActive.js +0 -11
  70. package/lib/relay-hooks/useLazyLoadQuery.js +0 -18
  71. package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -35
  72. package/lib/relay-hooks/useLoadMoreFunction.js +9 -34
  73. package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -11
  74. package/lib/relay-hooks/useMemoVariables.js +0 -17
  75. package/lib/relay-hooks/useMutation.js +0 -11
  76. package/lib/relay-hooks/usePaginationFragment.js +1 -26
  77. package/lib/relay-hooks/usePreloadedQuery.js +0 -27
  78. package/lib/relay-hooks/useQueryLoader.js +0 -74
  79. package/lib/relay-hooks/useRefetchableFragment.js +0 -16
  80. package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -97
  81. package/lib/relay-hooks/useRelayEnvironment.js +0 -11
  82. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -15
  83. package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -25
  84. package/lib/relay-hooks/useSubscription.js +0 -15
  85. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +0 -17
  86. package/package.json +2 -2
  87. package/react-relay-hooks.js +2 -2
  88. package/react-relay-hooks.min.js +2 -2
  89. package/react-relay-legacy.js +2 -2
  90. package/react-relay-legacy.min.js +2 -2
  91. package/react-relay.js +2 -2
  92. package/react-relay.min.js +2 -2
  93. package/relay-hooks/EntryPointContainer.react.js.flow +5 -0
  94. package/relay-hooks/EntryPointTypes.flow.js.flow +20 -19
  95. package/relay-hooks/FragmentResource.js.flow +114 -26
  96. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -2
  97. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
  98. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +7 -5
  99. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +5 -0
  100. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +5 -0
  101. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +2 -0
  102. package/relay-hooks/loadEntryPoint.js.flow +4 -2
  103. package/relay-hooks/loadQuery.js.flow +21 -1
  104. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +4 -2
  105. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +2 -1
  106. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +28 -10
  107. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +3 -9
  108. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +28 -57
  109. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +19 -12
  110. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +15 -31
  111. package/relay-hooks/useBlockingPaginationFragment.js.flow +2 -4
  112. package/relay-hooks/useClientQuery.js.flow +2 -2
  113. package/relay-hooks/useFragmentNode.js.flow +2 -2
  114. package/relay-hooks/useLoadMoreFunction.js.flow +15 -9
  115. package/relay-hooks/useMutation.js.flow +26 -9
  116. package/relay-hooks/usePaginationFragment.js.flow +2 -8
  117. package/relay-hooks/useQueryLoader.js.flow +2 -8
  118. package/relay-hooks/useRefetchableFragment.js.flow +3 -2
  119. package/relay-hooks/useRefetchableFragmentNode.js.flow +28 -13
@@ -1,33 +1,7 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- * @format
8
- * @oncall relay
9
- */
10
-
11
- /* global jest */
12
-
13
- // This file is sync'd from https://github.com/facebook/react/tree/main/packages/jest-react
14
-
15
- // This version of `act` is only used by our tests. Unlike the public version
16
- // of `act`, it's designed to work identically in both production and
17
- // development. It may have slightly different behavior from the public
18
- // version, too, since our constraints in our test suite are not the same as
19
- // those of developers using React — we're testing React itself, as opposed to
20
- // building an app with React.
21
-
22
1
  'use strict';
23
2
 
24
3
  var enqueueTask = require('./enqueueTask');
25
4
  var Scheduler = require('scheduler/unstable_mock');
26
-
27
- // The subset of a Promise that React APIs rely on. This resolves a value.
28
- // This doesn't require a return value neither from the handler nor the
29
- // then function.
30
-
31
5
  var actingUpdatesScopeDepth = 0;
32
6
  function act(scope) {
33
7
  if (Scheduler.unstable_flushAllWithoutAsserting === undefined) {
@@ -40,8 +14,6 @@ function act(scope) {
40
14
  var previousActingUpdatesScopeDepth = actingUpdatesScopeDepth;
41
15
  actingUpdatesScopeDepth++;
42
16
  if (process.env.NODE_ENV !== "production" && actingUpdatesScopeDepth === 1) {
43
- // Because this is not the "real" `act`, we set this to `false` so React
44
- // knows not to fire `act` warnings.
45
17
  global.IS_REACT_ACT_ENVIRONMENT = false;
46
18
  }
47
19
  var unwind = function unwind() {
@@ -51,16 +23,10 @@ function act(scope) {
51
23
  actingUpdatesScopeDepth--;
52
24
  if (process.env.NODE_ENV !== "production") {
53
25
  if (actingUpdatesScopeDepth > previousActingUpdatesScopeDepth) {
54
- // if it's _less than_ previousActingUpdatesScopeDepth, then we can
55
- // assume the 'other' one has warned
56
26
  console.error('You seem to have overlapping act() calls, this is not supported. ' + 'Be sure to await previous act() calls before making a new one. ');
57
27
  }
58
28
  }
59
29
  };
60
-
61
- // TODO: This would be way simpler if 1) we required a promise to be
62
- // returned and 2) we could use async/await. Since it's only our used in
63
- // our test suite, we should be able to.
64
30
  try {
65
31
  var result = scope();
66
32
  if (typeof result === 'object' && result !== null && typeof result.then === 'function') {
@@ -84,8 +50,6 @@ function act(scope) {
84
50
  } else {
85
51
  var returnValue = result;
86
52
  try {
87
- // TODO: Let's not support non-async scopes at all in our tests. Need to
88
- // migrate existing tests.
89
53
  var didFlushWork;
90
54
  do {
91
55
  didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
@@ -105,8 +69,6 @@ function act(scope) {
105
69
  }
106
70
  }
107
71
  function flushActWork(resolve, reject) {
108
- // Flush suspended fallbacks
109
- // $FlowFixMe: Flow doesn't know about global Jest object
110
72
  jest.runOnlyPendingTimers();
111
73
  enqueueTask(function () {
112
74
  try {
package/lib/legacy.js CHANGED
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var ReactRelayContext = require('./ReactRelayContext');
@@ -18,10 +7,6 @@ var ReactRelayPaginationContainer = require('./ReactRelayPaginationContainer');
18
7
  var ReactRelayQueryRenderer = require('./ReactRelayQueryRenderer');
19
8
  var ReactRelayRefetchContainer = require('./ReactRelayRefetchContainer');
20
9
  var RelayRuntime = require('relay-runtime');
21
- /**
22
- * Legacy react-relay exports.
23
- * Should prefer using interface defined in ./hooks.js
24
- */
25
10
  module.exports = {
26
11
  ConnectionHandler: RelayRuntime.ConnectionHandler,
27
12
  QueryRenderer: ReactRelayQueryRenderer,
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var RelayEnvironmentProvider = require('../relay-hooks/RelayEnvironmentProvider');
@@ -1,12 +1 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var ReactRelayContext = require('./../ReactRelayContext');
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var ProfilerContext = require('./ProfilerContext');
@@ -1,14 +1 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
- 'use strict';
13
-
14
- /* eslint-disable no-unused-vars */
1
+ 'use strict';
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"];
@@ -34,12 +23,7 @@ var _require2 = require('relay-runtime'),
34
23
  isPromise = _require2.isPromise,
35
24
  recycleNodesInto = _require2.recycleNodesInto;
36
25
  var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
37
- // TODO: Fix to not rely on LRU. If the number of active fragments exceeds this
38
- // capacity, readSpec() will fail to find cached entries and break object
39
- // identity even if data hasn't changed.
40
26
  var CACHE_CAPACITY = 1000000;
41
-
42
- // this is frozen so that users don't accidentally push data into the array
43
27
  var CONSTANT_READONLY_EMPTY_ARRAY = Object.freeze([]);
44
28
  function isMissingData(snapshot) {
45
29
  if (Array.isArray(snapshot)) {
@@ -94,13 +78,6 @@ function getFragmentResult(cacheKey, snapshot, storeEpoch) {
94
78
  storeEpoch: storeEpoch
95
79
  };
96
80
  }
97
-
98
- /**
99
- * The purpose of this cache is to allow information to be passed from an
100
- * initial read which suspends through to the commit that follows a subsequent
101
- * successful read. Specifically, the QueryResource result for the data fetch
102
- * is passed through so that that query can be retained on commit.
103
- */
104
81
  var ClientEdgeQueryResultsCache = /*#__PURE__*/function () {
105
82
  function ClientEdgeQueryResultsCache(environment) {
106
83
  (0, _defineProperty2["default"])(this, "_cache", new Map());
@@ -112,8 +89,7 @@ var ClientEdgeQueryResultsCache = /*#__PURE__*/function () {
112
89
  var _this$_cache$get$, _this$_cache$get;
113
90
  return (_this$_cache$get$ = (_this$_cache$get = this._cache.get(fragmentIdentifier)) === null || _this$_cache$get === void 0 ? void 0 : _this$_cache$get[0]) !== null && _this$_cache$get$ !== void 0 ? _this$_cache$get$ : undefined;
114
91
  };
115
- _proto.recordQueryResults = function recordQueryResults(fragmentIdentifier, value // may be mutated after being passed here
116
- ) {
92
+ _proto.recordQueryResults = function recordQueryResults(fragmentIdentifier, value) {
117
93
  var _this = this;
118
94
  var existing = this._cache.get(fragmentIdentifier);
119
95
  if (!existing) {
@@ -159,30 +135,14 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
159
135
  this._clientEdgeQueryResultsCache = new ClientEdgeQueryResultsCache(environment);
160
136
  }
161
137
  }
162
-
163
- /**
164
- * This function should be called during a Component's render function,
165
- * to read the data for a fragment, or suspend if the fragment is being
166
- * fetched.
167
- */
168
138
  var _proto2 = FragmentResourceImpl.prototype;
169
139
  _proto2.read = function read(fragmentNode, fragmentRef, componentDisplayName, fragmentKey) {
170
140
  return this.readWithIdentifier(fragmentNode, fragmentRef, getFragmentIdentifier(fragmentNode, fragmentRef), componentDisplayName, fragmentKey);
171
- }
172
-
173
- /**
174
- * Like `read`, but with a pre-computed fragmentIdentifier that should be
175
- * equal to `getFragmentIdentifier(fragmentNode, fragmentRef)` from the
176
- * arguments.
177
- */;
141
+ };
178
142
  _proto2.readWithIdentifier = function readWithIdentifier(fragmentNode, fragmentRef, fragmentIdentifier, componentDisplayName, fragmentKey) {
179
143
  var _this3 = this;
180
144
  var _fragmentNode$metadat, _fragmentNode$metadat2, _missingLiveResolverF2, _missingLiveResolverF3;
181
145
  var environment = this._environment;
182
-
183
- // If fragmentRef is null or undefined, pass it directly through.
184
- // This is a convenience when consuming fragments via a HOC API, when the
185
- // prop corresponding to the fragment ref might be passed as null.
186
146
  if (fragmentRef == null) {
187
147
  return {
188
148
  cacheKey: fragmentIdentifier,
@@ -193,9 +153,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
193
153
  };
194
154
  }
195
155
  var storeEpoch = environment.getStore().getEpoch();
196
-
197
- // If fragmentRef is plural, ensure that it is an array.
198
- // If it's empty, return the empty array directly before doing any more work.
199
156
  if ((fragmentNode === null || fragmentNode === void 0 ? void 0 : (_fragmentNode$metadat = fragmentNode.metadata) === null || _fragmentNode$metadat === void 0 ? void 0 : _fragmentNode$metadat.plural) === true) {
200
157
  !Array.isArray(fragmentRef) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected fragment pointer%s for fragment `%s` to be ' + 'an array, instead got `%s`. Remove `@relay(plural: true)` ' + 'from fragment `%s` to allow the prop to be an object.', fragmentKey != null ? " for key `".concat(fragmentKey, "`") : '', fragmentNode.name, typeof fragmentRef, fragmentNode.name) : invariant(false) : void 0;
201
158
  if (fragmentRef.length === 0) {
@@ -208,10 +165,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
208
165
  };
209
166
  }
210
167
  }
211
-
212
- // Now we actually attempt to read the fragment:
213
-
214
- // 1. Check if there's a cached value for this fragment
215
168
  var cachedValue = this._cache.get(fragmentIdentifier);
216
169
  if (cachedValue != null) {
217
170
  var _missingLiveResolverF;
@@ -228,13 +181,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
228
181
  throw cachedValue.promise;
229
182
  }
230
183
  if (cachedValue.kind === 'done' && cachedValue.result.snapshot && !((_missingLiveResolverF = missingLiveResolverFields(cachedValue.result.snapshot)) !== null && _missingLiveResolverF !== void 0 && _missingLiveResolverF.length)) {
231
- this._throwOrLogErrorsInSnapshot(
232
- // $FlowFixMe[incompatible-call]
233
- cachedValue.result.snapshot);
234
-
235
- // This cache gets populated directly whenever the store notifies us of
236
- // an update. That mechanism does not check for missing data, or
237
- // in-flight requests.
184
+ this._throwOrLogErrorsInSnapshot(cachedValue.result.snapshot);
238
185
  if (cachedValue.result.isMissingData) {
239
186
  environment.__log({
240
187
  name: 'fragmentresource.missing_data',
@@ -247,15 +194,19 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
247
194
  return cachedValue.result;
248
195
  }
249
196
  }
250
-
251
- // 2. If not, try reading the fragment from the Relay store.
252
- // If the snapshot has data, return it and save it in cache
253
197
  var fragmentSelector = getSelector(fragmentNode, fragmentRef);
254
198
  !(fragmentSelector != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to receive an object where `...%s` was spread, ' + 'but the fragment reference was not found`. This is most ' + 'likely the result of:\n' + "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" + '- Conditionally fetching `%s` but unconditionally passing %s prop ' + 'to `%s`. If the parent fragment only fetches the fragment conditionally ' + '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' + 'spread - then the fragment reference will not exist. ' + 'In this case, pass `null` if the conditions for evaluating the ' + 'fragment are not met (e.g. if the `@include(if)` value is false.)', fragmentNode.name, fragmentNode.name, componentDisplayName, fragmentNode.name, fragmentKey == null ? 'a fragment reference' : "the `".concat(fragmentKey, "`"), componentDisplayName) : invariant(false) : void 0;
255
- var snapshot = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors.map(function (s) {
256
- return environment.lookup(s);
257
- }) : environment.lookup(fragmentSelector);
258
- var fragmentResult = getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
199
+ var fragmentResult = null;
200
+ var snapshot = null;
201
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && cachedValue != null && cachedValue.kind === 'missing') {
202
+ fragmentResult = cachedValue.result;
203
+ snapshot = cachedValue.snapshot;
204
+ } else {
205
+ snapshot = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors.map(function (s) {
206
+ return environment.lookup(s);
207
+ }) : environment.lookup(fragmentSelector);
208
+ fragmentResult = getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
209
+ }
259
210
  if (!fragmentResult.isMissingData) {
260
211
  this._throwOrLogErrorsInSnapshot(snapshot);
261
212
  this._cache.set(fragmentIdentifier, {
@@ -264,17 +215,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
264
215
  });
265
216
  return fragmentResult;
266
217
  }
267
-
268
- // 3. If we don't have data in the store, there's two cases where we should
269
- // suspend to await the data: First if any client edges were traversed where
270
- // the destination record was missing data; in that case we initiate a query
271
- // here to fetch the missing data. Second, there may already be a request
272
- // in flight for the fragment's parent query, or for another operation that
273
- // may affect the parent's query data, such as a mutation or subscription.
274
- // For any of these cases we can get a promise, which we will cache and
275
- // suspend on.
276
-
277
- // First, initiate a query for any client edges that were missing data:
278
218
  var clientEdgeRequests = null;
279
219
  if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && ((_fragmentNode$metadat2 = fragmentNode.metadata) === null || _fragmentNode$metadat2 === void 0 ? void 0 : _fragmentNode$metadat2.hasClientEdges) === true && hasMissingClientEdges(snapshot)) {
280
220
  clientEdgeRequests = [];
@@ -293,8 +233,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
293
233
  (_clientEdgeRequests = clientEdgeRequests) === null || _clientEdgeRequests === void 0 ? void 0 : _clientEdgeRequests.push(requestDescriptor);
294
234
  });
295
235
  });
296
- // Store the query so that it can be retained when our own fragment is
297
- // subscribed to. This merges with any existing query results:
298
236
  !(this._clientEdgeQueryResultsCache != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Client edge query result cache should exist when ENABLE_CLIENT_EDGES is on.') : invariant(false) : void 0;
299
237
  this._clientEdgeQueryResultsCache.recordQueryResults(fragmentIdentifier, queryResults);
300
238
  }
@@ -304,16 +242,12 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
304
242
  return getPromiseForActiveRequest(_this3._environment, request);
305
243
  }).filter(Boolean);
306
244
  }
307
-
308
- // Finally look for operations in flight for our parent query:
309
245
  var fragmentOwner = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors[0].owner : fragmentSelector.owner;
310
246
  var parentQueryPromiseResult = this._getAndSavePromiseForFragmentRequestInFlight(fragmentIdentifier, fragmentNode, fragmentOwner, fragmentResult);
311
- var parentQueryPromiseResultPromise = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.promise; // for refinement
247
+ var parentQueryPromiseResultPromise = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.promise;
312
248
  var missingResolverFieldPromises = (_missingLiveResolverF2 = (_missingLiveResolverF3 = missingLiveResolverFields(snapshot)) === null || _missingLiveResolverF3 === void 0 ? void 0 : _missingLiveResolverF3.map(function (_ref2) {
313
249
  var liveStateID = _ref2.liveStateID;
314
250
  var store = environment.getStore();
315
-
316
- // $FlowFixMe[prop-missing] This is expected to be a LiveResolverStore
317
251
  return store.getLiveResolverPromise(liveStateID);
318
252
  })) !== null && _missingLiveResolverF2 !== void 0 ? _missingLiveResolverF2 : [];
319
253
  if (clientEdgePromises.length || missingResolverFieldPromises.length || isPromise(parentQueryPromiseResultPromise)) {
@@ -325,7 +259,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
325
259
  isRelayHooks: true,
326
260
  isPromiseCached: false,
327
261
  isMissingData: fragmentResult.isMissingData,
328
- // TODO! Attach information here about missing live resolver fields
329
262
  pendingOperations: [].concat((0, _toConsumableArray2["default"])((_parentQueryPromiseRe = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.pendingOperations) !== null && _parentQueryPromiseRe !== void 0 ? _parentQueryPromiseRe : []), (0, _toConsumableArray2["default"])((_clientEdgeRequests2 = clientEdgeRequests) !== null && _clientEdgeRequests2 !== void 0 ? _clientEdgeRequests2 : []))
330
263
  });
331
264
  var promises = [];
@@ -341,20 +274,17 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
341
274
  }
342
275
  throw Promise.all(promises);
343
276
  }
344
-
345
- // Note: we are re-throwing the `parentQueryPromiseResultPromise` here,
346
- // because some of our suspense-related code is relying on the instance equality
347
- // of thrown promises. See FragmentResource-test.js
348
277
  if (parentQueryPromiseResultPromise) {
349
278
  throw parentQueryPromiseResultPromise;
350
279
  }
351
280
  }
281
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && fragmentResult.isMissingData) {
282
+ this._cache.set(fragmentIdentifier, {
283
+ kind: 'done',
284
+ result: fragmentResult
285
+ });
286
+ }
352
287
  this._throwOrLogErrorsInSnapshot(snapshot);
353
-
354
- // At this point, there's nothing we can do. We don't have all the expected
355
- // data, but there's no indication the missing data will be fulfilled. So we
356
- // choose to return potentially non-typesafe data. The data returned here
357
- // might not match the generated types for this fragment/operation.
358
288
  environment.__log({
359
289
  name: 'fragmentresource.missing_data',
360
290
  data: fragmentResult.data,
@@ -367,17 +297,11 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
367
297
  _proto2._performClientEdgeQuery = function _performClientEdgeQuery(queryResource, fragmentNode, fragmentRef, request, clientEdgeDestinationID) {
368
298
  var originalVariables = getVariablesFromFragment(fragmentNode, fragmentRef);
369
299
  var variables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, originalVariables), {}, {
370
- id: clientEdgeDestinationID // TODO should be a reserved name
300
+ id: clientEdgeDestinationID
371
301
  });
372
-
373
- var operation = createOperationDescriptor(request, variables, {} // TODO cacheConfig should probably inherent from parent operation
374
- );
375
-
302
+ var operation = createOperationDescriptor(request, variables, {});
376
303
  var fetchObservable = fetchQuery(this._environment, operation);
377
- var queryResult = queryResource.prepare(operation, fetchObservable
378
- // TODO should inherent render policy etc. from parent operation
379
- );
380
-
304
+ var queryResult = queryResource.prepare(operation, fetchObservable);
381
305
  return {
382
306
  requestDescriptor: operation.request,
383
307
  queryResult: queryResult
@@ -410,20 +334,12 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
410
334
  dispose: function dispose() {}
411
335
  };
412
336
  }
413
-
414
- // 1. Check for any updates missed during render phase
415
- // TODO(T44066760): More efficiently detect if we missed an update
416
337
  var _this$checkMissedUpda = this.checkMissedUpdates(fragmentResult),
417
338
  didMissUpdates = _this$checkMissedUpda[0],
418
339
  currentSnapshot = _this$checkMissedUpda[1];
419
-
420
- // 2. If an update was missed, notify the component so it updates with
421
- // the latest data.
422
340
  if (didMissUpdates) {
423
341
  callback();
424
342
  }
425
-
426
- // 3. Establish subscriptions on the snapshot(s)
427
343
  var disposables = [];
428
344
  if (Array.isArray(renderedSnapshot)) {
429
345
  !Array.isArray(currentSnapshot) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshots to be plural. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
@@ -438,10 +354,19 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
438
354
  !(currentSnapshot != null && !Array.isArray(currentSnapshot)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshot to be singular. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
439
355
  disposables.push(environment.subscribe(currentSnapshot, function (latestSnapshot) {
440
356
  var storeEpoch = environment.getStore().getEpoch();
441
- _this5._cache.set(cacheKey, {
442
- kind: 'done',
443
- result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch)
444
- });
357
+ var result = getFragmentResult(cacheKey, latestSnapshot, storeEpoch);
358
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && result.isMissingData) {
359
+ _this5._cache.set(cacheKey, {
360
+ kind: 'missing',
361
+ result: result,
362
+ snapshot: latestSnapshot
363
+ });
364
+ } else {
365
+ _this5._cache.set(cacheKey, {
366
+ kind: 'done',
367
+ result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch)
368
+ });
369
+ }
445
370
  callback();
446
371
  }));
447
372
  }
@@ -484,7 +409,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
484
409
  return [false, null];
485
410
  }
486
411
  var storeEpoch = null;
487
- // Bail out if the store hasn't been written since last read
488
412
  storeEpoch = environment.getStore().getEpoch();
489
413
  if (fragmentResult.storeEpoch === storeEpoch) {
490
414
  return [false, fragmentResult.snapshot];
@@ -506,13 +430,20 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
506
430
  }
507
431
  currentSnapshots[idx] = currentSnapshot;
508
432
  });
509
- // Only update the cache when the data is changed to avoid
510
- // returning different `data` instances
511
433
  if (didMissUpdates) {
512
- this._cache.set(cacheKey, {
513
- kind: 'done',
514
- result: getFragmentResult(cacheKey, currentSnapshots, storeEpoch)
515
- });
434
+ var result = getFragmentResult(cacheKey, currentSnapshots, storeEpoch);
435
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && result.isMissingData) {
436
+ this._cache.set(cacheKey, {
437
+ kind: 'missing',
438
+ result: result,
439
+ snapshot: currentSnapshots
440
+ });
441
+ } else {
442
+ this._cache.set(cacheKey, {
443
+ kind: 'done',
444
+ result: result
445
+ });
446
+ }
516
447
  }
517
448
  return [didMissUpdates, currentSnapshots];
518
449
  }
@@ -531,10 +462,19 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
531
462
  relayResolverErrors: currentSnapshot.relayResolverErrors
532
463
  };
533
464
  if (updatedData !== renderData) {
534
- this._cache.set(cacheKey, {
535
- kind: 'done',
536
- result: getFragmentResult(cacheKey, updatedCurrentSnapshot, storeEpoch)
537
- });
465
+ var _result = getFragmentResult(cacheKey, updatedCurrentSnapshot, storeEpoch);
466
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && _result.isMissingData) {
467
+ this._cache.set(cacheKey, {
468
+ kind: 'missing',
469
+ result: _result,
470
+ snapshot: updatedCurrentSnapshot
471
+ });
472
+ } else {
473
+ this._cache.set(cacheKey, {
474
+ kind: 'done',
475
+ result: _result
476
+ });
477
+ }
538
478
  }
539
479
  return [updatedData !== renderData, updatedCurrentSnapshot];
540
480
  };
@@ -550,10 +490,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
550
490
  if (pendingOperationsResult == null) {
551
491
  return null;
552
492
  }
553
-
554
- // When the Promise for the request resolves, we need to make sure to
555
- // update the cache with the latest data available in the store before
556
- // resolving the Promise
557
493
  var networkPromise = pendingOperationsResult.promise;
558
494
  var pendingOperations = pendingOperationsResult.pendingOperations;
559
495
  var promise = networkPromise.then(function () {
@@ -561,7 +497,6 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
561
497
  })["catch"](function (error) {
562
498
  _this8._cache["delete"](cacheKey);
563
499
  });
564
- // $FlowExpectedError[prop-missing] Expando to annotate Promises.
565
500
  promise.displayName = networkPromise.displayName;
566
501
  this._cache.set(cacheKey, {
567
502
  kind: 'pending',
@@ -588,10 +523,19 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
588
523
  }
589
524
  var nextSnapshots = currentSnapshot ? (0, _toConsumableArray2["default"])(currentSnapshot) : (0, _toConsumableArray2["default"])(baseSnapshots);
590
525
  nextSnapshots[idx] = latestSnapshot;
591
- this._cache.set(cacheKey, {
592
- kind: 'done',
593
- result: getFragmentResult(cacheKey, nextSnapshots, storeEpoch)
594
- });
526
+ var result = getFragmentResult(cacheKey, nextSnapshots, storeEpoch);
527
+ if (RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE && result.isMissingData) {
528
+ this._cache.set(cacheKey, {
529
+ kind: 'missing',
530
+ result: result,
531
+ snapshot: nextSnapshots
532
+ });
533
+ } else {
534
+ this._cache.set(cacheKey, {
535
+ kind: 'done',
536
+ result: result
537
+ });
538
+ }
595
539
  };
596
540
  return FragmentResourceImpl;
597
541
  }();
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var warning = require("fbjs/lib/warning");
@@ -1,14 +1,3 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var loggerImpl = function loggerImpl(eventData) {};
@@ -1,28 +1,6 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- *
8
- * @format
9
- * @oncall relay
10
- */
11
-
12
1
  'use strict';
13
2
 
14
3
  var invariant = require('invariant');
15
- /**
16
- * JS maps (both plain objects and Map) maintain key insertion
17
- * order, which means there is an easy way to simulate LRU behavior
18
- * that should also perform quite well:
19
- *
20
- * To insert a new value, first delete the key from the inner _map,
21
- * then _map.set(k, v). By deleting and reinserting, you ensure that the
22
- * map sees the key as the last inserted key.
23
- *
24
- * Get does the same: if the key is present, delete and reinsert it.
25
- */
26
4
  var LRUCache = /*#__PURE__*/function () {
27
5
  function LRUCache(capacity) {
28
6
  this._capacity = capacity;