react-relay 11.0.1 → 13.0.0-rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayContext.js.flow +2 -3
  3. package/ReactRelayFragmentContainer.js.flow +24 -24
  4. package/ReactRelayFragmentMockRenderer.js.flow +1 -1
  5. package/ReactRelayLocalQueryRenderer.js.flow +6 -7
  6. package/ReactRelayPaginationContainer.js.flow +111 -58
  7. package/ReactRelayQueryFetcher.js.flow +9 -10
  8. package/ReactRelayQueryRenderer.js.flow +115 -81
  9. package/ReactRelayRefetchContainer.js.flow +41 -38
  10. package/ReactRelayTestMocker.js.flow +16 -14
  11. package/ReactRelayTypes.js.flow +10 -10
  12. package/RelayContext.js.flow +3 -3
  13. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +1 -2
  14. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +11 -7
  15. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +10 -6
  16. package/__flowtests__/RelayModern-flowtest.js.flow +78 -46
  17. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +5 -4
  18. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +5 -4
  19. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +4 -3
  20. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +4 -3
  21. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +72 -0
  22. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +72 -0
  23. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +227 -0
  24. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +164 -0
  25. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +227 -0
  26. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +164 -0
  27. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +66 -0
  28. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +66 -0
  29. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +59 -0
  30. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +61 -0
  31. package/assertFragmentMap.js.flow +2 -2
  32. package/buildReactRelayContainer.js.flow +15 -12
  33. package/getRootVariablesForFragments.js.flow +2 -4
  34. package/hooks.js +1 -1
  35. package/hooks.js.flow +5 -6
  36. package/index.js +1 -1
  37. package/index.js.flow +6 -7
  38. package/jest-react/enqueueTask.js.flow +56 -0
  39. package/jest-react/index.js.flow +12 -0
  40. package/jest-react/internalAct.js.flow +139 -0
  41. package/legacy.js +1 -1
  42. package/lib/ReactRelayFragmentContainer.js +21 -15
  43. package/lib/ReactRelayFragmentMockRenderer.js +2 -2
  44. package/lib/ReactRelayLocalQueryRenderer.js +7 -8
  45. package/lib/ReactRelayPaginationContainer.js +96 -38
  46. package/lib/ReactRelayQueryFetcher.js +3 -3
  47. package/lib/ReactRelayQueryRenderer.js +86 -53
  48. package/lib/ReactRelayRefetchContainer.js +38 -25
  49. package/lib/ReactRelayTestMocker.js +8 -9
  50. package/lib/RelayContext.js +3 -2
  51. package/lib/assertFragmentMap.js +3 -2
  52. package/lib/buildReactRelayContainer.js +14 -11
  53. package/lib/getRootVariablesForFragments.js +1 -2
  54. package/lib/hooks.js +5 -5
  55. package/lib/index.js +7 -7
  56. package/lib/jest-react/enqueueTask.js +53 -0
  57. package/lib/jest-react/index.js +13 -0
  58. package/lib/jest-react/internalAct.js +116 -0
  59. package/lib/multi-actor/ActorChange.js +30 -0
  60. package/lib/multi-actor/index.js +11 -0
  61. package/lib/multi-actor/useRelayActorEnvironment.js +29 -0
  62. package/lib/relay-hooks/EntryPointContainer.react.js +3 -3
  63. package/lib/relay-hooks/FragmentResource.js +347 -92
  64. package/lib/relay-hooks/LRUCache.js +1 -1
  65. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +4 -4
  66. package/lib/relay-hooks/MatchContainer.js +1 -1
  67. package/lib/relay-hooks/QueryResource.js +172 -29
  68. package/lib/relay-hooks/RelayEnvironmentProvider.js +5 -3
  69. package/lib/relay-hooks/SuspenseResource.js +130 -0
  70. package/lib/relay-hooks/loadQuery.js +42 -20
  71. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +24 -15
  72. package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -5
  73. package/lib/relay-hooks/useEntryPointLoader.js +2 -2
  74. package/lib/relay-hooks/useFetchTrackingRef.js +2 -1
  75. package/lib/relay-hooks/useFragment.js +8 -7
  76. package/lib/relay-hooks/useFragmentNode.js +4 -4
  77. package/lib/relay-hooks/useIsOperationNodeActive.js +3 -3
  78. package/lib/relay-hooks/useLazyLoadQuery.js +3 -3
  79. package/lib/relay-hooks/useLazyLoadQueryNode.js +10 -4
  80. package/lib/relay-hooks/useLoadMoreFunction.js +8 -12
  81. package/lib/relay-hooks/useMemoOperationDescriptor.js +2 -2
  82. package/lib/relay-hooks/useMemoVariables.js +2 -2
  83. package/lib/relay-hooks/useMutation.js +17 -6
  84. package/lib/relay-hooks/usePaginationFragment.js +2 -3
  85. package/lib/relay-hooks/usePreloadedQuery.js +8 -7
  86. package/lib/relay-hooks/useQueryLoader.js +30 -10
  87. package/lib/relay-hooks/useRefetchableFragmentNode.js +13 -17
  88. package/lib/relay-hooks/useRelayEnvironment.js +3 -3
  89. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -2
  90. package/lib/relay-hooks/useSubscribeToInvalidationState.js +2 -1
  91. package/lib/relay-hooks/useSubscription.js +10 -7
  92. package/multi-actor/ActorChange.js.flow +58 -0
  93. package/multi-actor/index.js.flow +14 -0
  94. package/multi-actor/useRelayActorEnvironment.js.flow +49 -0
  95. package/package.json +3 -2
  96. package/react-relay-hooks.js +2 -2
  97. package/react-relay-hooks.min.js +2 -2
  98. package/react-relay-legacy.js +2 -2
  99. package/react-relay-legacy.min.js +2 -2
  100. package/react-relay.js +2 -2
  101. package/react-relay.min.js +2 -2
  102. package/relay-hooks/EntryPointContainer.react.js.flow +8 -15
  103. package/relay-hooks/EntryPointTypes.flow.js.flow +24 -25
  104. package/relay-hooks/FragmentResource.js.flow +368 -94
  105. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +32 -46
  106. package/relay-hooks/MatchContainer.js.flow +3 -2
  107. package/relay-hooks/QueryResource.js.flow +216 -25
  108. package/relay-hooks/RelayEnvironmentProvider.js.flow +14 -4
  109. package/relay-hooks/SuspenseResource.js.flow +115 -0
  110. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +4 -3
  111. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +1 -1
  112. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +10 -9
  113. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +8 -7
  114. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +10 -9
  115. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +10 -9
  116. package/relay-hooks/__flowtests__/utils.js.flow +8 -12
  117. package/relay-hooks/loadEntryPoint.js.flow +6 -12
  118. package/relay-hooks/loadQuery.js.flow +49 -31
  119. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +30 -21
  120. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +6 -12
  121. package/relay-hooks/useBlockingPaginationFragment.js.flow +13 -11
  122. package/relay-hooks/useEntryPointLoader.js.flow +7 -10
  123. package/relay-hooks/useFetchTrackingRef.js.flow +2 -2
  124. package/relay-hooks/useFragment.js.flow +26 -46
  125. package/relay-hooks/useFragmentNode.js.flow +5 -7
  126. package/relay-hooks/useIsOperationNodeActive.js.flow +3 -5
  127. package/relay-hooks/useIsParentQueryActive.js.flow +3 -4
  128. package/relay-hooks/useLazyLoadQuery.js.flow +9 -10
  129. package/relay-hooks/useLazyLoadQueryNode.js.flow +19 -13
  130. package/relay-hooks/useLoadMoreFunction.js.flow +20 -29
  131. package/relay-hooks/useMemoOperationDescriptor.js.flow +5 -7
  132. package/relay-hooks/useMemoVariables.js.flow +6 -6
  133. package/relay-hooks/useMutation.js.flow +26 -26
  134. package/relay-hooks/usePaginationFragment.js.flow +38 -44
  135. package/relay-hooks/usePreloadedQuery.js.flow +18 -14
  136. package/relay-hooks/useQueryLoader.js.flow +41 -22
  137. package/relay-hooks/useRefetchableFragment.js.flow +7 -8
  138. package/relay-hooks/useRefetchableFragmentNode.js.flow +24 -32
  139. package/relay-hooks/useRelayEnvironment.js.flow +2 -4
  140. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +2 -3
  141. package/relay-hooks/useSubscribeToInvalidationState.js.flow +3 -6
  142. package/relay-hooks/useSubscription.js.flow +20 -10
  143. package/lib/relay-hooks/getPaginationMetadata.js +0 -41
  144. package/lib/relay-hooks/getPaginationVariables.js +0 -67
  145. package/lib/relay-hooks/getRefetchMetadata.js +0 -36
  146. package/lib/relay-hooks/getValueAtPath.js +0 -51
  147. package/relay-hooks/getPaginationMetadata.js.flow +0 -74
  148. package/relay-hooks/getPaginationVariables.js.flow +0 -110
  149. package/relay-hooks/getRefetchMetadata.js.flow +0 -80
  150. package/relay-hooks/getValueAtPath.js.flow +0 -46
@@ -12,19 +12,6 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
- const ReactRelayContext = require('./ReactRelayContext');
17
- const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
18
- const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
19
-
20
- const areEqual = require('areEqual');
21
-
22
- const {
23
- createOperationDescriptor,
24
- deepFreeze,
25
- getRequest,
26
- } = require('relay-runtime');
27
-
28
15
  import type {ReactRelayQueryRendererContext as ReactRelayQueryRendererContextType} from './ReactRelayQueryRendererContext';
29
16
  import type {
30
17
  CacheConfig,
@@ -35,7 +22,20 @@ import type {
35
22
  Snapshot,
36
23
  Variables,
37
24
  } from 'relay-runtime';
38
- type RetryCallbacks = {
25
+
26
+ const ReactRelayContext = require('./ReactRelayContext');
27
+ const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
28
+ const ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
29
+ const areEqual = require('areEqual');
30
+ const React = require('react');
31
+ const {
32
+ RelayFeatureFlags,
33
+ createOperationDescriptor,
34
+ deepFreeze,
35
+ getRequest,
36
+ } = require('relay-runtime');
37
+
38
+ type RetryCallbacks = {|
39
39
  handleDataChange:
40
40
  | null
41
41
  | (({
@@ -44,8 +44,7 @@ type RetryCallbacks = {
44
44
  ...
45
45
  }) => void),
46
46
  handleRetryAfterError: null | ((error: Error) => void),
47
- ...
48
- };
47
+ |};
49
48
 
50
49
  export type RenderProps<T> = {|
51
50
  error: ?Error,
@@ -96,6 +95,8 @@ type State = {|
96
95
  * - Subscribes for updates to the root data and re-renders with any changes.
97
96
  */
98
97
  class ReactRelayQueryRenderer extends React.Component<Props, State> {
98
+ _maybeHiddenOrFastRefresh: boolean;
99
+
99
100
  constructor(props: Props) {
100
101
  super(props);
101
102
 
@@ -124,6 +125,8 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
124
125
  queryFetcher = new ReactRelayQueryFetcher();
125
126
  }
126
127
 
128
+ this._maybeHiddenOrFastRefresh = false;
129
+
127
130
  this.state = {
128
131
  prevPropsEnvironment: props.environment,
129
132
  prevPropsVariables: props.variables,
@@ -148,77 +151,37 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
148
151
  prevState.prevPropsEnvironment !== nextProps.environment ||
149
152
  !areEqual(prevState.prevPropsVariables, nextProps.variables)
150
153
  ) {
151
- const {query} = nextProps;
152
- const prevSelectionReferences = prevState.queryFetcher.getSelectionReferences();
153
- prevState.queryFetcher.disposeRequest();
154
-
155
- let queryFetcher;
156
- if (query) {
157
- const request = getRequest(query);
158
- const requestCacheKey = getRequestCacheKey(
159
- request.params,
160
- nextProps.variables,
161
- );
162
- queryFetcher = requestCache[requestCacheKey]
163
- ? requestCache[requestCacheKey].queryFetcher
164
- : new ReactRelayQueryFetcher(prevSelectionReferences);
165
- } else {
166
- queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
167
- }
168
- return {
169
- prevQuery: nextProps.query,
170
- prevPropsEnvironment: nextProps.environment,
171
- prevPropsVariables: nextProps.variables,
172
- queryFetcher: queryFetcher,
173
- ...fetchQueryAndComputeStateFromProps(
174
- nextProps,
175
- queryFetcher,
176
- prevState.retryCallbacks,
177
- // passing no requestCacheKey will cause it to be recalculated internally
178
- // and we want the updated requestCacheKey, since variables may have changed
179
- ),
180
- };
154
+ return resetQueryStateForUpdate(nextProps, prevState);
181
155
  }
182
-
183
156
  return null;
184
157
  }
185
158
 
186
159
  componentDidMount() {
160
+ if (
161
+ RelayFeatureFlags.ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT === true &&
162
+ this._maybeHiddenOrFastRefresh === true
163
+ ) {
164
+ // This block only runs if the component has previously "unmounted"
165
+ // due to it being hidden by the Offscreen API, or during fast refresh.
166
+ // At this point, the current cached resource will have been disposed
167
+ // by the previous cleanup, so instead of attempting to
168
+ // do our regular commit setup, so that the query is re-evaluated
169
+ // (and potentially cause a refetch).
170
+ this._maybeHiddenOrFastRefresh = false;
171
+ // eslint-disable-next-line react/no-did-mount-set-state
172
+ this.setState(prevState => {
173
+ return resetQueryStateForUpdate(this.props, prevState);
174
+ });
175
+ return;
176
+ }
177
+
187
178
  const {retryCallbacks, queryFetcher, requestCacheKey} = this.state;
179
+ // We don't need to cache the request after the component commits
188
180
  if (requestCacheKey) {
189
181
  delete requestCache[requestCacheKey];
190
182
  }
191
183
 
192
- retryCallbacks.handleDataChange = (params: {
193
- error?: Error,
194
- snapshot?: Snapshot,
195
- ...
196
- }): void => {
197
- const error = params.error == null ? null : params.error;
198
- const snapshot = params.snapshot == null ? null : params.snapshot;
199
-
200
- this.setState(prevState => {
201
- const {requestCacheKey: prevRequestCacheKey} = prevState;
202
- if (prevRequestCacheKey) {
203
- delete requestCache[prevRequestCacheKey];
204
- }
205
-
206
- // Don't update state if nothing has changed.
207
- if (snapshot === prevState.snapshot && error === prevState.error) {
208
- return null;
209
- }
210
- return {
211
- renderProps: getRenderProps(
212
- error,
213
- snapshot,
214
- prevState.queryFetcher,
215
- prevState.retryCallbacks,
216
- ),
217
- snapshot,
218
- requestCacheKey: null,
219
- };
220
- });
221
- };
184
+ retryCallbacks.handleDataChange = this._handleDataChange;
222
185
 
223
186
  retryCallbacks.handleRetryAfterError = (error: Error) =>
224
187
  this.setState(prevState => {
@@ -236,22 +199,27 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
236
199
  // Re-initialize the ReactRelayQueryFetcher with callbacks.
237
200
  // If data has changed since constructions, this will re-render.
238
201
  if (this.props.query) {
239
- queryFetcher.setOnDataChange(retryCallbacks.handleDataChange);
202
+ queryFetcher.setOnDataChange(this._handleDataChange);
240
203
  }
241
204
  }
242
205
 
243
- componentDidUpdate(): void {
206
+ componentDidUpdate(_prevProps: Props, prevState: State): void {
244
207
  // We don't need to cache the request after the component commits
245
- const {requestCacheKey} = this.state;
208
+ const {queryFetcher, requestCacheKey} = this.state;
246
209
  if (requestCacheKey) {
247
210
  delete requestCache[requestCacheKey];
248
211
  // HACK
249
212
  delete this.state.requestCacheKey;
250
213
  }
214
+
215
+ if (this.props.query && queryFetcher !== prevState.queryFetcher) {
216
+ queryFetcher.setOnDataChange(this._handleDataChange);
217
+ }
251
218
  }
252
219
 
253
220
  componentWillUnmount(): void {
254
221
  this.state.queryFetcher.dispose();
222
+ this._maybeHiddenOrFastRefresh = true;
255
223
  }
256
224
 
257
225
  shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
@@ -261,6 +229,37 @@ class ReactRelayQueryRenderer extends React.Component<Props, State> {
261
229
  );
262
230
  }
263
231
 
232
+ _handleDataChange = (params: {
233
+ error?: Error,
234
+ snapshot?: Snapshot,
235
+ ...
236
+ }): void => {
237
+ const error = params.error == null ? null : params.error;
238
+ const snapshot = params.snapshot == null ? null : params.snapshot;
239
+
240
+ this.setState(prevState => {
241
+ const {requestCacheKey: prevRequestCacheKey} = prevState;
242
+ if (prevRequestCacheKey) {
243
+ delete requestCache[prevRequestCacheKey];
244
+ }
245
+
246
+ // Don't update state if nothing has changed.
247
+ if (snapshot === prevState.snapshot && error === prevState.error) {
248
+ return null;
249
+ }
250
+ return {
251
+ renderProps: getRenderProps(
252
+ error,
253
+ snapshot,
254
+ prevState.queryFetcher,
255
+ prevState.retryCallbacks,
256
+ ),
257
+ snapshot,
258
+ requestCacheKey: null,
259
+ };
260
+ });
261
+ };
262
+
264
263
  render(): React.Element<typeof ReactRelayContext.Provider> {
265
264
  const {renderProps, relayContext} = this.state;
266
265
  // Note that the root fragment results in `renderProps.props` is already
@@ -334,6 +333,41 @@ function getRequestCacheKey(
334
333
  });
335
334
  }
336
335
 
336
+ function resetQueryStateForUpdate(
337
+ props: Props,
338
+ prevState: State,
339
+ ): $Shape<State> {
340
+ const {query} = props;
341
+
342
+ const prevSelectionReferences =
343
+ prevState.queryFetcher.getSelectionReferences();
344
+ prevState.queryFetcher.disposeRequest();
345
+
346
+ let queryFetcher;
347
+ if (query) {
348
+ const request = getRequest(query);
349
+ const requestCacheKey = getRequestCacheKey(request.params, props.variables);
350
+ queryFetcher = requestCache[requestCacheKey]
351
+ ? requestCache[requestCacheKey].queryFetcher
352
+ : new ReactRelayQueryFetcher(prevSelectionReferences);
353
+ } else {
354
+ queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
355
+ }
356
+ return {
357
+ prevQuery: props.query,
358
+ prevPropsEnvironment: props.environment,
359
+ prevPropsVariables: props.variables,
360
+ queryFetcher: queryFetcher,
361
+ ...fetchQueryAndComputeStateFromProps(
362
+ props,
363
+ queryFetcher,
364
+ prevState.retryCallbacks,
365
+ // passing no requestCacheKey will cause it to be recalculated internally
366
+ // and we want the updated requestCacheKey, since variables may have changed
367
+ ),
368
+ };
369
+ }
370
+
337
371
  function fetchQueryAndComputeStateFromProps(
338
372
  props: Props,
339
373
  queryFetcher: ReactRelayQueryFetcher,
@@ -390,7 +424,7 @@ function fetchQueryAndComputeStateFromProps(
390
424
  );
391
425
  const querySnapshot = queryFetcher.fetch({
392
426
  environment: genericEnvironment,
393
- onDataChange: retryCallbacks.handleDataChange,
427
+ onDataChange: null,
394
428
  operation,
395
429
  });
396
430
 
@@ -12,34 +12,12 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
- const ReactRelayContext = require('./ReactRelayContext');
17
- const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
18
-
19
- const areEqual = require('areEqual');
20
- const buildReactRelayContainer = require('./buildReactRelayContainer');
21
- const getRootVariablesForFragments = require('./getRootVariablesForFragments');
22
- const warning = require('warning');
23
-
24
- const {getContainerName} = require('./ReactRelayContainerUtils');
25
- const {assertRelayContext} = require('./RelayContext');
26
- const {
27
- Observable,
28
- createFragmentSpecResolver,
29
- createOperationDescriptor,
30
- getDataIDsFromObject,
31
- getRequest,
32
- getSelector,
33
- getVariablesFromObject,
34
- isScalarAndEqual,
35
- } = require('relay-runtime');
36
-
37
15
  import type {
38
- $RelayProps,
39
- ObserverOrCallback,
40
16
  GeneratedNodeMap,
17
+ ObserverOrCallback,
41
18
  RefetchOptions,
42
19
  RelayRefetchProp,
20
+ $RelayProps,
43
21
  } from './ReactRelayTypes';
44
22
  import type {
45
23
  CacheConfig,
@@ -52,6 +30,25 @@ import type {
52
30
  } from 'relay-runtime';
53
31
  import type {FragmentSpecResolver} from 'relay-runtime';
54
32
 
33
+ const buildReactRelayContainer = require('./buildReactRelayContainer');
34
+ const getRootVariablesForFragments = require('./getRootVariablesForFragments');
35
+ const {getContainerName} = require('./ReactRelayContainerUtils');
36
+ const ReactRelayContext = require('./ReactRelayContext');
37
+ const ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
38
+ const {assertRelayContext} = require('./RelayContext');
39
+ const areEqual = require('areEqual');
40
+ const React = require('react');
41
+ const {
42
+ Observable,
43
+ createFragmentSpecResolver,
44
+ createOperationDescriptor,
45
+ getDataIDsFromObject,
46
+ getRequest,
47
+ getVariablesFromObject,
48
+ isScalarAndEqual,
49
+ } = require('relay-runtime');
50
+ const warning = require('warning');
51
+
55
52
  type ContainerProps = $FlowFixMeProps;
56
53
 
57
54
  type ContainerState = {
@@ -119,7 +116,7 @@ function createContainerWithFragments<
119
116
 
120
117
  componentDidMount() {
121
118
  this._isUnmounted = false;
122
- this._subscribeToNewResolver();
119
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
123
120
  }
124
121
 
125
122
  componentDidUpdate(prevProps: ContainerProps, prevState: ContainerState) {
@@ -133,7 +130,9 @@ function createContainerWithFragments<
133
130
  this._queryFetcher && this._queryFetcher.dispose();
134
131
  this._refetchSubscription && this._refetchSubscription.unsubscribe();
135
132
 
136
- this._subscribeToNewResolver();
133
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
134
+ } else {
135
+ this._rerenderIfStoreHasChanged();
137
136
  }
138
137
  }
139
138
 
@@ -250,16 +249,26 @@ function createContainerWithFragments<
250
249
  return false;
251
250
  }
252
251
 
253
- _subscribeToNewResolver() {
252
+ _rerenderIfStoreHasChanged() {
254
253
  const {data, resolver} = this.state;
254
+ // External values could change between render and commit.
255
+ // Check for this case, even though it requires an extra store read.
256
+ const maybeNewData = resolver.resolve();
257
+ if (data !== maybeNewData) {
258
+ this.setState({data: maybeNewData});
259
+ }
260
+ }
261
+
262
+ _subscribeToNewResolverAndRerenderIfStoreHasChanged() {
263
+ const {data, resolver} = this.state;
264
+ const maybeNewData = resolver.resolve();
255
265
 
256
266
  // Event listeners are only safe to add during the commit phase,
257
267
  // So they won't leak if render is interrupted or errors.
258
- resolver.setCallback(this._handleFragmentDataUpdate);
268
+ resolver.setCallback(this.props, this._handleFragmentDataUpdate);
259
269
 
260
270
  // External values could change between render and commit.
261
271
  // Check for this case, even though it requires an extra store read.
262
- const maybeNewData = resolver.resolve();
263
272
  if (data !== maybeNewData) {
264
273
  this.setState({data: maybeNewData});
265
274
  }
@@ -321,11 +330,9 @@ function createContainerWithFragments<
321
330
  typeof refetchVariables === 'function'
322
331
  ? refetchVariables(this._getFragmentVariables())
323
332
  : refetchVariables;
324
- // $FlowFixMe[cannot-spread-interface]
325
333
  fetchVariables = {...rootVariables, ...fetchVariables};
326
334
  const fragmentVariables = renderVariables
327
- ? // $FlowFixMe[cannot-spread-interface]
328
- {...fetchVariables, ...renderVariables}
335
+ ? {...fetchVariables, ...renderVariables}
329
336
  : fetchVariables;
330
337
 
331
338
  const cacheConfig: ?CacheConfig = options
@@ -441,12 +448,8 @@ function createContainerWithFragments<
441
448
  };
442
449
 
443
450
  render() {
444
- const {
445
- componentRef,
446
- __relayContext,
447
- __rootIsQueryRenderer,
448
- ...props
449
- } = this.props;
451
+ const {componentRef, __relayContext, __rootIsQueryRenderer, ...props} =
452
+ this.props;
450
453
  const {relayProp, contextForChildren} = this.state;
451
454
  return (
452
455
  <ReactRelayContext.Provider value={contextForChildren}>
@@ -12,16 +12,6 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const areEqual = require('areEqual');
16
- const invariant = require('invariant');
17
- const warning = require('warning');
18
-
19
- const {
20
- createOperationDescriptor,
21
- isRelayModernEnvironment,
22
- Network,
23
- } = require('relay-runtime');
24
-
25
15
  import type {
26
16
  CacheConfig,
27
17
  ConcreteRequest,
@@ -32,6 +22,15 @@ import type {
32
22
  Variables,
33
23
  } from 'relay-runtime';
34
24
 
25
+ const areEqual = require('areEqual');
26
+ const invariant = require('invariant');
27
+ const {
28
+ Network,
29
+ createOperationDescriptor,
30
+ isRelayModernEnvironment,
31
+ } = require('relay-runtime');
32
+ const warning = require('warning');
33
+
35
34
  export type DataWriteConfig = {
36
35
  query: ConcreteRequest,
37
36
  variables: Variables,
@@ -66,7 +65,7 @@ let nextId = 0;
66
65
 
67
66
  class ReactRelayTestMocker {
68
67
  _environment: IEnvironment;
69
- _defaults: {[string]: $PropertyType<NetworkWriteConfig, 'payload'>, ...} = {};
68
+ _defaults: {[string]: NetworkWriteConfig['payload'], ...} = {};
70
69
  _pendingFetches: Array<PendingFetch> = [];
71
70
 
72
71
  constructor(env: IEnvironment) {
@@ -118,7 +117,6 @@ class ReactRelayTestMocker {
118
117
  * annoying to test (e.g. client_mutation_id, actor_id)
119
118
  */
120
119
  static stripUnused(variables: Variables): Variables {
121
- // $FlowFixMe[prop-missing]
122
120
  if (variables.input) {
123
121
  const toRemove = [
124
122
  'client_mutation_id',
@@ -126,7 +124,6 @@ class ReactRelayTestMocker {
126
124
  'clientMutationId',
127
125
  'actorId',
128
126
  ];
129
- // $FlowFixMe[cannot-spread-interface]
130
127
  const strippedVariables = {...variables, input: {...variables.input}};
131
128
  toRemove.forEach(item => (strippedVariables.input[item] = undefined));
132
129
  return strippedVariables;
@@ -143,7 +140,11 @@ class ReactRelayTestMocker {
143
140
  * their components behave under error conditions.
144
141
  */
145
142
  _mockNetworkLayer(env: IEnvironment): IEnvironment {
146
- const fetch = (request, variables, cacheConfig) => {
143
+ const fetch = (
144
+ request: RequestParameters,
145
+ variables: Variables,
146
+ cacheConfig: CacheConfig,
147
+ ) => {
147
148
  let resolve;
148
149
  let reject;
149
150
  const promise = new Promise((res, rej) => {
@@ -314,6 +315,7 @@ class ReactRelayTestMocker {
314
315
  );
315
316
 
316
317
  const realPayload =
318
+ // $FlowFixMe[incompatible-call]
317
319
  typeof payload === 'function' ? payload(toResolve.variables) : payload;
318
320
 
319
321
  // if there are errors, reject the query
@@ -14,7 +14,7 @@
14
14
 
15
15
  import type {
16
16
  Disposable,
17
- FragmentReference,
17
+ FragmentType,
18
18
  GraphQLTaggedNode,
19
19
  IEnvironment,
20
20
  Observer,
@@ -94,7 +94,7 @@ export type RefetchOptions = {|
94
94
  *
95
95
  */
96
96
  export type $FragmentRef<T> = {
97
- +$fragmentRefs: $PropertyType<T, '$refType'>,
97
+ +$fragmentSpreads: T['$fragmentType'],
98
98
  ...
99
99
  };
100
100
 
@@ -105,14 +105,14 @@ export type $FragmentRef<T> = {
105
105
  // prettier-ignore
106
106
  export type $RelayProps<Props, RelayPropT = RelayProp> = $ObjMap<
107
107
  $Diff<Props, { relay: RelayPropT | void, ... }>,
108
- & (<T: { +$refType: empty, ... }>( T) => T)
109
- & (<T: { +$refType: empty, ... }>(?T) => ?T)
110
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( T ) => $FragmentRef<T> )
111
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(? T ) => ? $FragmentRef<T> )
112
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( $ReadOnlyArray< T>) => $ReadOnlyArray< $FragmentRef<T>>)
113
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(?$ReadOnlyArray< T>) => ?$ReadOnlyArray< $FragmentRef<T>>)
114
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>( $ReadOnlyArray<?T>) => $ReadOnlyArray<?$FragmentRef<T>>)
115
- & (<TRef: FragmentReference, T: { +$refType: TRef, ... }>(?$ReadOnlyArray<?T>) => ?$ReadOnlyArray<?$FragmentRef<T>>)
108
+ & (<T: { +$fragmentType: empty, ... }>( T) => T)
109
+ & (<T: { +$fragmentType: empty, ... }>(?T) => ?T)
110
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( T ) => $FragmentRef<T> )
111
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(? T ) => ? $FragmentRef<T> )
112
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( $ReadOnlyArray< T>) => $ReadOnlyArray< $FragmentRef<T>>)
113
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(?$ReadOnlyArray< T>) => ?$ReadOnlyArray< $FragmentRef<T>>)
114
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>( $ReadOnlyArray<?T>) => $ReadOnlyArray<?$FragmentRef<T>>)
115
+ & (<TFragmentType: FragmentType, T: { +$fragmentType: TFragmentType, ... }>(?$ReadOnlyArray<?T>) => ?$ReadOnlyArray<?$FragmentRef<T>>)
116
116
  & (<T>(T) => T),
117
117
  >;
118
118
 
@@ -12,11 +12,11 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const invariant = require('invariant');
16
- const isRelayEnvironment = require('./isRelayEnvironment');
17
-
18
15
  import type {RelayContext} from 'relay-runtime';
19
16
 
17
+ const isRelayEnvironment = require('./isRelayEnvironment');
18
+ const invariant = require('invariant');
19
+
20
20
  /**
21
21
  * Asserts that the input is a matches the `RelayContext` type defined in
22
22
  * `RelayEnvironmentTypes` and returns it as that type.
@@ -12,11 +12,10 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
-
17
15
  const {
18
16
  createContainer: createFragmentContainer,
19
17
  } = require('../ReactRelayFragmentContainer');
18
+ const React = require('react');
20
19
  const {graphql} = require('relay-runtime');
21
20
 
22
21
  /**
@@ -12,11 +12,10 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
-
17
15
  const {
18
16
  createContainer: createPaginationContainer,
19
17
  } = require('../ReactRelayPaginationContainer');
18
+ const React = require('react');
20
19
  const {graphql} = require('relay-runtime');
21
20
 
22
21
  /**
@@ -63,10 +62,15 @@ const Foo = createPaginationContainer(
63
62
  {
64
63
  viewer: graphql`
65
64
  fragment ReactRelayPaginationContainerFlowtest_viewer on Viewer {
66
- all_friends(after: $cursor, first: $count) @connection {
67
- edges {
68
- node {
69
- __typename
65
+ account_user {
66
+ friends(after: $cursor, first: $count)
67
+ @connection(
68
+ key: "ReactRelayPaginationContainerFlowtest_viewer__friends"
69
+ ) {
70
+ edges {
71
+ node {
72
+ __typename
73
+ }
70
74
  }
71
75
  }
72
76
  }
@@ -75,7 +79,7 @@ const Foo = createPaginationContainer(
75
79
  },
76
80
  {
77
81
  direction: 'forward',
78
- getConnectionFromProps: props => props.viewer.all_friends,
82
+ getConnectionFromProps: props => props.viewer.account_user.friends,
79
83
  // $FlowFixMe[cannot-spread-interface]
80
84
  getFragmentVariables: (vars, totalCount) => ({
81
85
  ...vars,
@@ -12,11 +12,10 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const React = require('react');
16
-
17
15
  const {
18
16
  createContainer: createRefetchContainer,
19
17
  } = require('../ReactRelayRefetchContainer');
18
+ const React = require('react');
20
19
  const {graphql} = require('relay-runtime');
21
20
 
22
21
  /**
@@ -62,10 +61,15 @@ const Foo = createRefetchContainer(
62
61
  {
63
62
  viewer: graphql`
64
63
  fragment ReactRelayRefetchContainerFlowtest_viewer on Viewer {
65
- all_friends(after: $cursor, first: $count) @connection {
66
- edges {
67
- node {
68
- __typename
64
+ account_user {
65
+ friends(after: $cursor, first: $count)
66
+ @connection(
67
+ key: "ReactRelayRefetchContainerFlowtest_viewer__friends"
68
+ ) {
69
+ edges {
70
+ node {
71
+ __typename
72
+ }
69
73
  }
70
74
  }
71
75
  }