react-relay 13.1.1 → 14.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. package/ReactRelayContainerUtils.js.flow +0 -2
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +0 -2
  4. package/ReactRelayFragmentContainer.js.flow +7 -6
  5. package/ReactRelayFragmentMockRenderer.js.flow +0 -2
  6. package/ReactRelayLocalQueryRenderer.js.flow +1 -3
  7. package/ReactRelayPaginationContainer.js.flow +13 -10
  8. package/ReactRelayQueryFetcher.js.flow +10 -11
  9. package/ReactRelayQueryRenderer.js.flow +15 -16
  10. package/ReactRelayQueryRendererContext.js.flow +1 -3
  11. package/ReactRelayRefetchContainer.js.flow +10 -7
  12. package/ReactRelayTestMocker.js.flow +0 -2
  13. package/ReactRelayTypes.js.flow +6 -8
  14. package/RelayContext.js.flow +0 -2
  15. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -4
  16. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +3 -5
  17. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +3 -5
  18. package/__flowtests__/RelayModern-flowtest.js.flow +2 -4
  19. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +2 -4
  20. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +2 -4
  21. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +2 -4
  22. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +2 -4
  23. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +2 -2
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +2 -2
  25. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +3 -3
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -3
  27. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +3 -3
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -3
  29. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +2 -2
  30. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +2 -2
  31. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +2 -2
  32. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +2 -2
  33. package/assertFragmentMap.js.flow +0 -2
  34. package/buildReactRelayContainer.js.flow +2 -4
  35. package/getRootVariablesForFragments.js.flow +0 -2
  36. package/hooks.js +1 -1
  37. package/hooks.js.flow +0 -2
  38. package/index.js +1 -1
  39. package/index.js.flow +2 -2
  40. package/isRelayEnvironment.js.flow +0 -2
  41. package/jest-react/internalAct.js.flow +25 -9
  42. package/legacy.js +1 -1
  43. package/legacy.js.flow +0 -2
  44. package/lib/ReactRelayContainerUtils.js +0 -1
  45. package/lib/ReactRelayContext.js +0 -1
  46. package/lib/ReactRelayFragmentContainer.js +10 -9
  47. package/lib/ReactRelayFragmentMockRenderer.js +0 -1
  48. package/lib/ReactRelayLocalQueryRenderer.js +0 -1
  49. package/lib/ReactRelayPaginationContainer.js +14 -11
  50. package/lib/ReactRelayQueryFetcher.js +2 -2
  51. package/lib/ReactRelayQueryRenderer.js +2 -4
  52. package/lib/ReactRelayQueryRendererContext.js +0 -1
  53. package/lib/ReactRelayRefetchContainer.js +11 -14
  54. package/lib/ReactRelayTestMocker.js +1 -2
  55. package/lib/ReactRelayTypes.js +0 -1
  56. package/lib/RelayContext.js +0 -1
  57. package/lib/assertFragmentMap.js +0 -1
  58. package/lib/buildReactRelayContainer.js +1 -2
  59. package/lib/getRootVariablesForFragments.js +1 -2
  60. package/lib/hooks.js +0 -1
  61. package/lib/index.js +3 -1
  62. package/lib/isRelayEnvironment.js +0 -1
  63. package/lib/jest-react/internalAct.js +24 -4
  64. package/lib/legacy.js +0 -1
  65. package/lib/multi-actor/useRelayActorEnvironment.js +0 -1
  66. package/lib/readContext.js +2 -2
  67. package/lib/relay-hooks/EntryPointContainer.react.js +0 -1
  68. package/lib/relay-hooks/EntryPointTypes.flow.js +0 -1
  69. package/lib/relay-hooks/FragmentResource.js +68 -29
  70. package/lib/relay-hooks/HooksImplementation.js +29 -0
  71. package/lib/relay-hooks/InternalLogger.js +0 -1
  72. package/lib/relay-hooks/LRUCache.js +0 -1
  73. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -1
  74. package/lib/relay-hooks/MatchContainer.js +2 -2
  75. package/lib/relay-hooks/ProfilerContext.js +0 -1
  76. package/lib/relay-hooks/QueryResource.js +5 -168
  77. package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -1
  78. package/lib/relay-hooks/SuspenseResource.js +1 -2
  79. package/lib/relay-hooks/loadQuery.js +1 -1
  80. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +8 -13
  81. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -1
  82. package/lib/relay-hooks/react-cache/RelayReactCache.js +36 -0
  83. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +344 -0
  84. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +239 -0
  85. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +598 -0
  86. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +50 -0
  87. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +55 -0
  88. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +150 -0
  89. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +124 -0
  90. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +367 -0
  91. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +45 -0
  92. package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -3
  93. package/lib/relay-hooks/useClientQuery.js +33 -0
  94. package/lib/relay-hooks/useEntryPointLoader.js +1 -2
  95. package/lib/relay-hooks/useFetchTrackingRef.js +0 -1
  96. package/lib/relay-hooks/useFragment.js +15 -2
  97. package/lib/relay-hooks/useFragmentNode.js +0 -1
  98. package/lib/relay-hooks/useIsMountedRef.js +0 -1
  99. package/lib/relay-hooks/useLazyLoadQuery.js +4 -2
  100. package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -1
  101. package/lib/relay-hooks/useLoadMoreFunction.js +1 -2
  102. package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -1
  103. package/lib/relay-hooks/useMemoVariables.js +0 -1
  104. package/lib/relay-hooks/useMutation.js +5 -7
  105. package/lib/relay-hooks/usePaginationFragment.js +15 -3
  106. package/lib/relay-hooks/usePreloadedQuery.js +4 -2
  107. package/lib/relay-hooks/useQueryLoader.js +1 -2
  108. package/lib/relay-hooks/useRefetchableFragment.js +14 -2
  109. package/lib/relay-hooks/useRefetchableFragmentNode.js +1 -2
  110. package/lib/relay-hooks/useRelayEnvironment.js +0 -1
  111. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -1
  112. package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -1
  113. package/lib/relay-hooks/useSubscription.js +0 -1
  114. package/multi-actor/useRelayActorEnvironment.js.flow +0 -2
  115. package/package.json +3 -3
  116. package/react-relay-hooks.js +2 -2
  117. package/react-relay-hooks.min.js +2 -2
  118. package/react-relay-legacy.js +2 -2
  119. package/react-relay-legacy.min.js +2 -2
  120. package/react-relay.js +2 -2
  121. package/react-relay.min.js +2 -2
  122. package/readContext.js.flow +1 -2
  123. package/relay-hooks/EntryPointContainer.react.js.flow +2 -4
  124. package/relay-hooks/EntryPointTypes.flow.js.flow +30 -32
  125. package/relay-hooks/FragmentResource.js.flow +80 -37
  126. package/relay-hooks/HooksImplementation.js.flow +43 -0
  127. package/relay-hooks/InternalLogger.js.flow +0 -2
  128. package/relay-hooks/LRUCache.js.flow +0 -2
  129. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -6
  130. package/relay-hooks/MatchContainer.js.flow +11 -6
  131. package/relay-hooks/ProfilerContext.js.flow +0 -2
  132. package/relay-hooks/QueryResource.js.flow +12 -209
  133. package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -4
  134. package/relay-hooks/SuspenseResource.js.flow +0 -2
  135. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +3 -3
  136. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +2 -2
  137. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +2 -2
  138. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +2 -2
  139. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +4 -6
  140. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +0 -2
  141. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +4 -6
  142. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +0 -2
  143. package/relay-hooks/__flowtests__/utils.js.flow +8 -10
  144. package/relay-hooks/loadQuery.js.flow +2 -1
  145. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +11 -20
  146. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +0 -2
  147. package/relay-hooks/react-cache/RelayReactCache.js.flow +40 -0
  148. package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +430 -0
  149. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +297 -0
  150. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +599 -0
  151. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +72 -0
  152. package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +70 -0
  153. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +171 -0
  154. package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +151 -0
  155. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +595 -0
  156. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +65 -0
  157. package/relay-hooks/useBlockingPaginationFragment.js.flow +4 -6
  158. package/relay-hooks/useClientQuery.js.flow +39 -0
  159. package/relay-hooks/useEntryPointLoader.js.flow +6 -8
  160. package/relay-hooks/useFetchTrackingRef.js.flow +2 -4
  161. package/relay-hooks/useFragment.js.flow +17 -12
  162. package/relay-hooks/useFragmentNode.js.flow +2 -4
  163. package/relay-hooks/useIsMountedRef.js.flow +1 -3
  164. package/relay-hooks/useLazyLoadQuery.js.flow +17 -5
  165. package/relay-hooks/useLazyLoadQueryNode.js.flow +2 -4
  166. package/relay-hooks/useLoadMoreFunction.js.flow +6 -8
  167. package/relay-hooks/useMemoOperationDescriptor.js.flow +0 -2
  168. package/relay-hooks/useMemoVariables.js.flow +0 -2
  169. package/relay-hooks/useMutation.js.flow +5 -7
  170. package/relay-hooks/usePaginationFragment.js.flow +44 -19
  171. package/relay-hooks/usePreloadedQuery.js.flow +14 -5
  172. package/relay-hooks/useQueryLoader.js.flow +4 -6
  173. package/relay-hooks/useRefetchableFragment.js.flow +32 -3
  174. package/relay-hooks/useRefetchableFragmentNode.js.flow +38 -25
  175. package/relay-hooks/useRelayEnvironment.js.flow +0 -2
  176. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +0 -2
  177. package/relay-hooks/useSubscribeToInvalidationState.js.flow +0 -2
  178. package/relay-hooks/useSubscription.js.flow +14 -10
@@ -0,0 +1,297 @@
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
+ * @flow strict-local
8
+ * @emails oncall+relay
9
+ * @format
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ import type {QueryResult} from '../QueryResource';
15
+ import type {
16
+ CacheConfig,
17
+ FetchPolicy,
18
+ IEnvironment,
19
+ ReaderFragment,
20
+ ReaderSelector,
21
+ SelectorData,
22
+ Snapshot,
23
+ } from 'relay-runtime';
24
+ import type {MissingClientEdgeRequestInfo} from 'relay-runtime/store/RelayStoreTypes';
25
+
26
+ const {getQueryResourceForEnvironment} = require('../QueryResource');
27
+ const invariant = require('invariant');
28
+ const {
29
+ __internal: {fetchQuery: fetchQueryInternal},
30
+ createOperationDescriptor,
31
+ getPendingOperationsForFragment,
32
+ getSelector,
33
+ getVariablesFromFragment,
34
+ handlePotentialSnapshotErrors,
35
+ } = require('relay-runtime');
36
+ const warning = require('warning');
37
+
38
+ type FragmentQueryOptions = {
39
+ fetchPolicy?: FetchPolicy,
40
+ networkCacheConfig?: ?CacheConfig,
41
+ };
42
+
43
+ type FragmentState = $ReadOnly<
44
+ | {kind: 'bailout'}
45
+ | {kind: 'singular', snapshot: Snapshot, epoch: number}
46
+ | {kind: 'plural', snapshots: $ReadOnlyArray<Snapshot>, epoch: number},
47
+ >;
48
+
49
+ function isMissingData(state: FragmentState): boolean {
50
+ if (state.kind === 'bailout') {
51
+ return false;
52
+ } else if (state.kind === 'singular') {
53
+ return state.snapshot.isMissingData;
54
+ } else {
55
+ return state.snapshots.some(s => s.isMissingData);
56
+ }
57
+ }
58
+
59
+ function getMissingClientEdges(
60
+ state: FragmentState,
61
+ ): $ReadOnlyArray<MissingClientEdgeRequestInfo> | null {
62
+ if (state.kind === 'bailout') {
63
+ return null;
64
+ } else if (state.kind === 'singular') {
65
+ return state.snapshot.missingClientEdges ?? null;
66
+ } else {
67
+ let edges = null;
68
+ for (const snapshot of state.snapshots) {
69
+ if (snapshot.missingClientEdges) {
70
+ edges = edges ?? [];
71
+ for (const edge of snapshot.missingClientEdges) {
72
+ edges.push(edge);
73
+ }
74
+ }
75
+ }
76
+ return edges;
77
+ }
78
+ }
79
+
80
+ function handlePotentialSnapshotErrorsForState(
81
+ environment: IEnvironment,
82
+ state: FragmentState,
83
+ ): void {
84
+ if (state.kind === 'singular') {
85
+ handlePotentialSnapshotErrors(
86
+ environment,
87
+ state.snapshot.missingRequiredFields,
88
+ state.snapshot.relayResolverErrors,
89
+ );
90
+ } else if (state.kind === 'plural') {
91
+ for (const snapshot of state.snapshots) {
92
+ handlePotentialSnapshotErrors(
93
+ environment,
94
+ snapshot.missingRequiredFields,
95
+ snapshot.relayResolverErrors,
96
+ );
97
+ }
98
+ }
99
+ }
100
+
101
+ function handleMissingClientEdge(
102
+ environment: IEnvironment,
103
+ parentFragmentNode: ReaderFragment,
104
+ parentFragmentRef: mixed,
105
+ missingClientEdgeRequestInfo: MissingClientEdgeRequestInfo,
106
+ queryOptions?: FragmentQueryOptions,
107
+ ): QueryResult {
108
+ const originalVariables = getVariablesFromFragment(
109
+ parentFragmentNode,
110
+ parentFragmentRef,
111
+ );
112
+ const variables = {
113
+ ...originalVariables,
114
+ id: missingClientEdgeRequestInfo.clientEdgeDestinationID, // TODO should be a reserved name
115
+ };
116
+ const queryOperationDescriptor = createOperationDescriptor(
117
+ missingClientEdgeRequestInfo.request,
118
+ variables,
119
+ queryOptions?.networkCacheConfig,
120
+ );
121
+ // This may suspend. We don't need to do anything with the results; all we're
122
+ // doing here is started the query if needed and retaining and releasing it
123
+ // according to the component mount/suspense cycle; QueryResource
124
+ // already handles this by itself.
125
+ const QueryResource = getQueryResourceForEnvironment(environment);
126
+ return QueryResource.prepare(
127
+ queryOperationDescriptor,
128
+ fetchQueryInternal(environment, queryOperationDescriptor),
129
+ queryOptions?.fetchPolicy,
130
+ );
131
+ }
132
+
133
+ function getFragmentState(
134
+ environment: IEnvironment,
135
+ fragmentSelector: ?ReaderSelector,
136
+ ): FragmentState {
137
+ if (fragmentSelector == null) {
138
+ return {kind: 'bailout'};
139
+ } else if (fragmentSelector.kind === 'PluralReaderSelector') {
140
+ if (fragmentSelector.selectors.length === 0) {
141
+ return {kind: 'bailout'};
142
+ } else {
143
+ return {
144
+ kind: 'plural',
145
+ snapshots: fragmentSelector.selectors.map(s => environment.lookup(s)),
146
+ epoch: environment.getStore().getEpoch(),
147
+ };
148
+ }
149
+ } else {
150
+ return {
151
+ kind: 'singular',
152
+ snapshot: environment.lookup(fragmentSelector),
153
+ epoch: environment.getStore().getEpoch(),
154
+ };
155
+ }
156
+ }
157
+
158
+ // fragmentNode cannot change during the lifetime of the component, though fragmentRef may change.
159
+ function readFragmentInternal_REACT_CACHE(
160
+ environment: IEnvironment,
161
+ fragmentNode: ReaderFragment,
162
+ fragmentRef: mixed,
163
+ hookDisplayName: string,
164
+ queryOptions?: FragmentQueryOptions,
165
+ fragmentKey?: string,
166
+ ): {
167
+ +data: ?SelectorData | Array<?SelectorData>,
168
+ +clientEdgeQueries: ?Array<QueryResult>,
169
+ } {
170
+ const fragmentSelector = getSelector(fragmentNode, fragmentRef);
171
+ const isPlural = fragmentNode?.metadata?.plural === true;
172
+
173
+ if (isPlural) {
174
+ invariant(
175
+ fragmentRef == null || Array.isArray(fragmentRef),
176
+ 'Relay: Expected fragment pointer%s for fragment `%s` to be ' +
177
+ 'an array, instead got `%s`. Remove `@relay(plural: true)` ' +
178
+ 'from fragment `%s` to allow the prop to be an object.',
179
+ fragmentKey != null ? ` for key \`${fragmentKey}\`` : '',
180
+ fragmentNode.name,
181
+ typeof fragmentRef,
182
+ fragmentNode.name,
183
+ );
184
+ } else {
185
+ invariant(
186
+ !Array.isArray(fragmentRef),
187
+ 'Relay: Expected fragment pointer%s for fragment `%s` not to be ' +
188
+ 'an array, instead got `%s`. Add `@relay(plural: true)` ' +
189
+ 'to fragment `%s` to allow the prop to be an array.',
190
+ fragmentKey != null ? ` for key \`${fragmentKey}\`` : '',
191
+ fragmentNode.name,
192
+ typeof fragmentRef,
193
+ fragmentNode.name,
194
+ );
195
+ }
196
+ invariant(
197
+ fragmentRef == null ||
198
+ (isPlural && Array.isArray(fragmentRef) && fragmentRef.length === 0) ||
199
+ fragmentSelector != null,
200
+ 'Relay: Expected to receive an object where `...%s` was spread, ' +
201
+ 'but the fragment reference was not found`. This is most ' +
202
+ 'likely the result of:\n' +
203
+ "- Forgetting to spread `%s` in `%s`'s parent's fragment.\n" +
204
+ '- Conditionally fetching `%s` but unconditionally passing %s prop ' +
205
+ 'to `%s`. If the parent fragment only fetches the fragment conditionally ' +
206
+ '- with e.g. `@include`, `@skip`, or inside a `... on SomeType { }` ' +
207
+ 'spread - then the fragment reference will not exist. ' +
208
+ 'In this case, pass `null` if the conditions for evaluating the ' +
209
+ 'fragment are not met (e.g. if the `@include(if)` value is false.)',
210
+ fragmentNode.name,
211
+ fragmentNode.name,
212
+ hookDisplayName,
213
+ fragmentNode.name,
214
+ fragmentKey == null ? 'a fragment reference' : `the \`${fragmentKey}\``,
215
+ hookDisplayName,
216
+ );
217
+
218
+ const state = getFragmentState(environment, fragmentSelector);
219
+
220
+ // Handle the queries for any missing client edges; this may suspend.
221
+ // FIXME handle client edges in parallel.
222
+ let clientEdgeQueries = null;
223
+ if (fragmentNode.metadata?.hasClientEdges === true) {
224
+ const missingClientEdges = getMissingClientEdges(state);
225
+ if (missingClientEdges?.length) {
226
+ clientEdgeQueries = [];
227
+ for (const edge of missingClientEdges) {
228
+ clientEdgeQueries.push(
229
+ handleMissingClientEdge(
230
+ environment,
231
+ fragmentNode,
232
+ fragmentRef,
233
+ edge,
234
+ queryOptions,
235
+ ),
236
+ );
237
+ }
238
+ }
239
+ }
240
+
241
+ if (isMissingData(state)) {
242
+ // Suspend if an active operation bears on this fragment, either the
243
+ // fragment's owner or some other mutation etc. that could affect it:
244
+ invariant(fragmentSelector != null, 'refinement, see invariants above');
245
+ const fragmentOwner =
246
+ fragmentSelector.kind === 'PluralReaderSelector'
247
+ ? fragmentSelector.selectors[0].owner
248
+ : fragmentSelector.owner;
249
+ const pendingOperationsResult = getPendingOperationsForFragment(
250
+ environment,
251
+ fragmentNode,
252
+ fragmentOwner,
253
+ );
254
+ if (pendingOperationsResult) {
255
+ throw pendingOperationsResult.promise;
256
+ }
257
+ // Report required fields only if we're not suspending, since that means
258
+ // they're missing even though we are out of options for possibly fetching them:
259
+ handlePotentialSnapshotErrorsForState(environment, state);
260
+ }
261
+
262
+ let data: ?SelectorData | Array<?SelectorData>;
263
+ if (state.kind === 'bailout') {
264
+ data = isPlural ? [] : null;
265
+ } else if (state.kind === 'singular') {
266
+ data = state.snapshot.data;
267
+ } else {
268
+ data = state.snapshots.map(s => s.data);
269
+ }
270
+
271
+ if (__DEV__) {
272
+ if (
273
+ fragmentRef != null &&
274
+ (data === undefined ||
275
+ (Array.isArray(data) &&
276
+ data.length > 0 &&
277
+ data.every(d => d === undefined)))
278
+ ) {
279
+ warning(
280
+ false,
281
+ 'Relay: Expected to have been able to read non-null data for ' +
282
+ 'fragment `%s` declared in ' +
283
+ '`%s`, since fragment reference was non-null. ' +
284
+ "Make sure that that `%s`'s parent isn't " +
285
+ 'holding on to and/or passing a fragment reference for data that ' +
286
+ 'has been deleted.',
287
+ fragmentNode.name,
288
+ hookDisplayName,
289
+ hookDisplayName,
290
+ );
291
+ }
292
+ }
293
+
294
+ return {data, clientEdgeQueries};
295
+ }
296
+
297
+ module.exports = readFragmentInternal_REACT_CACHE;