react-relay 14.1.0 → 16.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. package/ReactRelayContainerUtils.js.flow +1 -0
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +1 -0
  4. package/ReactRelayFragmentContainer.js.flow +6 -2
  5. package/ReactRelayFragmentMockRenderer.js.flow +1 -0
  6. package/ReactRelayLocalQueryRenderer.js.flow +5 -3
  7. package/ReactRelayPaginationContainer.js.flow +21 -12
  8. package/ReactRelayQueryFetcher.js.flow +20 -10
  9. package/ReactRelayQueryRenderer.js.flow +15 -11
  10. package/ReactRelayQueryRendererContext.js.flow +1 -0
  11. package/ReactRelayRefetchContainer.js.flow +9 -5
  12. package/ReactRelayTestMocker.js.flow +3 -1
  13. package/ReactRelayTypes.js.flow +2 -0
  14. package/RelayContext.js.flow +1 -0
  15. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -1
  16. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +1 -0
  17. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +1 -0
  18. package/__flowtests__/RelayModern-flowtest.js.flow +1 -0
  19. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +1 -0
  20. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +1 -0
  21. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +1 -0
  22. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +1 -0
  23. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +3 -1
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +3 -1
  25. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +4 -2
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -1
  27. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +4 -2
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -1
  29. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +4 -2
  30. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +4 -2
  31. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +3 -1
  32. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +3 -1
  33. package/assertFragmentMap.js.flow +1 -0
  34. package/buildReactRelayContainer.js.flow +10 -6
  35. package/getRootVariablesForFragments.js.flow +1 -1
  36. package/hooks.js +1 -1
  37. package/hooks.js.flow +4 -0
  38. package/index.js +1 -1
  39. package/index.js.flow +4 -0
  40. package/isRelayEnvironment.js.flow +1 -0
  41. package/jest-react/enqueueTask.js.flow +1 -1
  42. package/jest-react/index.js.flow +1 -1
  43. package/jest-react/internalAct.js.flow +1 -1
  44. package/legacy.js +1 -1
  45. package/legacy.js.flow +1 -0
  46. package/lib/ReactRelayContainerUtils.js +0 -11
  47. package/lib/ReactRelayContext.js +1 -12
  48. package/lib/ReactRelayFragmentContainer.js +23 -122
  49. package/lib/ReactRelayFragmentMockRenderer.js +0 -12
  50. package/lib/ReactRelayLocalQueryRenderer.js +12 -41
  51. package/lib/ReactRelayPaginationContainer.js +45 -341
  52. package/lib/ReactRelayQueryFetcher.js +36 -111
  53. package/lib/ReactRelayQueryRenderer.js +29 -137
  54. package/lib/ReactRelayQueryRendererContext.js +0 -10
  55. package/lib/ReactRelayRefetchContainer.js +33 -166
  56. package/lib/ReactRelayTestMocker.js +18 -128
  57. package/lib/ReactRelayTypes.js +0 -9
  58. package/lib/RelayContext.js +0 -23
  59. package/lib/assertFragmentMap.js +0 -16
  60. package/lib/buildReactRelayContainer.js +7 -41
  61. package/lib/getRootVariablesForFragments.js +2 -19
  62. package/lib/hooks.js +3 -30
  63. package/lib/index.js +3 -39
  64. package/lib/isRelayEnvironment.js +1 -16
  65. package/lib/jest-react/enqueueTask.js +1 -25
  66. package/lib/jest-react/index.js +0 -1
  67. package/lib/jest-react/internalAct.js +2 -51
  68. package/lib/legacy.js +0 -20
  69. package/lib/multi-actor/ActorChange.js +0 -14
  70. package/lib/multi-actor/index.js +0 -10
  71. package/lib/multi-actor/useRelayActorEnvironment.js +2 -16
  72. package/lib/relay-hooks/EntryPointContainer.react.js +7 -23
  73. package/lib/relay-hooks/EntryPointTypes.flow.js +0 -10
  74. package/lib/relay-hooks/FragmentResource.js +130 -280
  75. package/lib/relay-hooks/HooksImplementation.js +0 -14
  76. package/lib/relay-hooks/InternalLogger.js +0 -11
  77. package/lib/relay-hooks/LRUCache.js +0 -39
  78. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +27 -65
  79. package/lib/relay-hooks/MatchContainer.js +9 -111
  80. package/lib/relay-hooks/NestedRelayEntryPointBuilderUtils.js +9 -0
  81. package/lib/relay-hooks/ProfilerContext.js +0 -14
  82. package/lib/relay-hooks/QueryResource.js +14 -149
  83. package/lib/relay-hooks/RelayEnvironmentProvider.js +3 -17
  84. package/lib/relay-hooks/SuspenseResource.js +2 -59
  85. package/lib/relay-hooks/loadEntryPoint.js +10 -45
  86. package/lib/relay-hooks/loadQuery.js +29 -169
  87. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +8 -58
  88. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +6 -24
  89. package/lib/relay-hooks/react-cache/RelayReactCache.js +4 -20
  90. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +13 -102
  91. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +18 -75
  92. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +79 -222
  93. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +3 -27
  94. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +11 -33
  95. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +62 -85
  96. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +20 -63
  97. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +53 -179
  98. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +5 -27
  99. package/lib/relay-hooks/useBlockingPaginationFragment.js +58 -121
  100. package/lib/relay-hooks/useClientQuery.js +0 -21
  101. package/lib/relay-hooks/useEntryPointLoader.js +12 -100
  102. package/lib/relay-hooks/useFetchTrackingRef.js +6 -33
  103. package/lib/relay-hooks/useFragment.js +5 -32
  104. package/lib/relay-hooks/useFragmentNode.js +14 -55
  105. package/lib/relay-hooks/useIsMountedRef.js +2 -14
  106. package/lib/relay-hooks/useIsOperationNodeActive.js +6 -29
  107. package/lib/relay-hooks/useIsParentQueryActive.js +1 -15
  108. package/lib/relay-hooks/useLazyLoadQuery.js +2 -23
  109. package/lib/relay-hooks/useLazyLoadQueryNode.js +18 -63
  110. package/lib/relay-hooks/useLoadMoreFunction.js +44 -100
  111. package/lib/relay-hooks/useMemoOperationDescriptor.js +4 -23
  112. package/lib/relay-hooks/useMemoVariables.js +8 -43
  113. package/lib/relay-hooks/useMutation.js +6 -34
  114. package/lib/relay-hooks/usePaginationFragment.js +49 -89
  115. package/lib/relay-hooks/usePreloadedQuery.js +10 -54
  116. package/lib/relay-hooks/useQueryLoader.js +18 -116
  117. package/lib/relay-hooks/useRefetchableFragment.js +4 -30
  118. package/lib/relay-hooks/useRefetchableFragmentNode.js +58 -184
  119. package/lib/relay-hooks/useRelayEnvironment.js +2 -16
  120. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -20
  121. package/lib/relay-hooks/useSubscribeToInvalidationState.js +3 -28
  122. package/lib/relay-hooks/useSubscription.js +3 -22
  123. package/lib/relay-hooks/useUnsafeRef_DEPRECATED.js +12 -0
  124. package/multi-actor/ActorChange.js.flow +1 -1
  125. package/multi-actor/index.js.flow +1 -1
  126. package/multi-actor/useRelayActorEnvironment.js.flow +2 -2
  127. package/package.json +2 -2
  128. package/react-relay-hooks.js +2 -2
  129. package/react-relay-hooks.min.js +2 -2
  130. package/react-relay-legacy.js +2 -2
  131. package/react-relay-legacy.min.js +2 -2
  132. package/react-relay.js +2 -2
  133. package/react-relay.min.js +2 -2
  134. package/relay-hooks/EntryPointContainer.react.js.flow +6 -1
  135. package/relay-hooks/EntryPointTypes.flow.js.flow +23 -20
  136. package/relay-hooks/FragmentResource.js.flow +148 -34
  137. package/relay-hooks/HooksImplementation.js.flow +1 -1
  138. package/relay-hooks/InternalLogger.js.flow +1 -1
  139. package/relay-hooks/LRUCache.js.flow +1 -1
  140. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +19 -10
  141. package/relay-hooks/MatchContainer.js.flow +1 -1
  142. package/relay-hooks/NestedRelayEntryPointBuilderUtils.js.flow +51 -0
  143. package/relay-hooks/ProfilerContext.js.flow +1 -1
  144. package/relay-hooks/QueryResource.js.flow +25 -5
  145. package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -2
  146. package/relay-hooks/SuspenseResource.js.flow +1 -1
  147. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +3 -1
  148. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +9 -7
  149. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +3 -1
  150. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +3 -1
  151. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +40 -33
  152. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +1 -1
  153. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +38 -32
  154. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +20 -18
  155. package/relay-hooks/__flowtests__/utils.js.flow +13 -2
  156. package/relay-hooks/loadEntryPoint.js.flow +15 -8
  157. package/relay-hooks/loadQuery.js.flow +32 -8
  158. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +5 -6
  159. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +17 -10
  160. package/relay-hooks/react-cache/RelayReactCache.js.flow +1 -1
  161. package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +4 -4
  162. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +5 -4
  163. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +32 -14
  164. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +4 -10
  165. package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +1 -1
  166. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +39 -49
  167. package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +1 -2
  168. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +29 -16
  169. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +17 -33
  170. package/relay-hooks/useBlockingPaginationFragment.js.flow +85 -58
  171. package/relay-hooks/useClientQuery.js.flow +3 -3
  172. package/relay-hooks/useEntryPointLoader.js.flow +10 -6
  173. package/relay-hooks/useFetchTrackingRef.js.flow +5 -4
  174. package/relay-hooks/useFragment.js.flow +2 -2
  175. package/relay-hooks/useFragmentNode.js.flow +7 -6
  176. package/relay-hooks/useIsMountedRef.js.flow +1 -1
  177. package/relay-hooks/useIsOperationNodeActive.js.flow +1 -1
  178. package/relay-hooks/useIsParentQueryActive.js.flow +1 -1
  179. package/relay-hooks/useLazyLoadQuery.js.flow +2 -2
  180. package/relay-hooks/useLazyLoadQueryNode.js.flow +2 -2
  181. package/relay-hooks/useLoadMoreFunction.js.flow +27 -16
  182. package/relay-hooks/useMemoOperationDescriptor.js.flow +3 -3
  183. package/relay-hooks/useMemoVariables.js.flow +13 -29
  184. package/relay-hooks/useMutation.js.flow +30 -13
  185. package/relay-hooks/usePaginationFragment.js.flow +55 -54
  186. package/relay-hooks/usePreloadedQuery.js.flow +47 -22
  187. package/relay-hooks/useQueryLoader.js.flow +78 -21
  188. package/relay-hooks/useRefetchableFragment.js.flow +65 -33
  189. package/relay-hooks/useRefetchableFragmentNode.js.flow +38 -17
  190. package/relay-hooks/useRelayEnvironment.js.flow +2 -2
  191. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -3
  192. package/relay-hooks/useSubscribeToInvalidationState.js.flow +2 -2
  193. package/relay-hooks/useSubscription.js.flow +1 -1
  194. package/relay-hooks/useUnsafeRef_DEPRECATED.js.flow +25 -0
  195. package/lib/readContext.js +0 -27
  196. package/readContext.js.flow +0 -29
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * @flow strict-local
8
- * @emails oncall+relay
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -29,8 +29,8 @@ const {getQueryResourceForEnvironment} = require('./QueryResource');
29
29
  const SuspenseResource = require('./SuspenseResource');
30
30
  const invariant = require('invariant');
31
31
  const {
32
- RelayFeatureFlags,
33
32
  __internal: {fetchQuery, getPromiseForActiveRequest},
33
+ RelayFeatureFlags,
34
34
  createOperationDescriptor,
35
35
  getFragmentIdentifier,
36
36
  getPendingOperationsForFragment,
@@ -50,7 +50,12 @@ type FragmentResourceCache = Cache<
50
50
  promise: Promise<mixed>,
51
51
  result: FragmentResult,
52
52
  }
53
- | {kind: 'done', result: FragmentResult},
53
+ | {kind: 'done', result: FragmentResult}
54
+ | {
55
+ kind: 'missing',
56
+ result: FragmentResult,
57
+ snapshot: SingularOrPluralSnapshot,
58
+ },
54
59
  >;
55
60
 
56
61
  const WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
@@ -75,7 +80,7 @@ opaque type FragmentResult: {data: mixed, ...} = {
75
80
  const CACHE_CAPACITY = 1000000;
76
81
 
77
82
  // this is frozen so that users don't accidentally push data into the array
78
- const CONSTANT_READONLY_EMPTY_ARRAY = Object.freeze([]);
83
+ const CONSTANT_READONLY_EMPTY_ARRAY: Array<$FlowFixMe> = Object.freeze([]);
79
84
 
80
85
  function isMissingData(snapshot: SingularOrPluralSnapshot): boolean {
81
86
  if (Array.isArray(snapshot)) {
@@ -304,9 +309,23 @@ class FragmentResourceImpl {
304
309
  cachedValue.result.snapshot &&
305
310
  !missingLiveResolverFields(cachedValue.result.snapshot)?.length
306
311
  ) {
307
- this._handlePotentialSnapshotErrorsInSnapshot(
312
+ this._throwOrLogErrorsInSnapshot(
313
+ // $FlowFixMe[incompatible-call]
308
314
  cachedValue.result.snapshot,
309
315
  );
316
+
317
+ // This cache gets populated directly whenever the store notifies us of
318
+ // an update. That mechanism does not check for missing data, or
319
+ // in-flight requests.
320
+ if (cachedValue.result.isMissingData) {
321
+ environment.__log({
322
+ name: 'fragmentresource.missing_data',
323
+ data: cachedValue.result.data,
324
+ fragment: fragmentNode,
325
+ isRelayHooks: true,
326
+ cached: true,
327
+ });
328
+ }
310
329
  return cachedValue.result;
311
330
  }
312
331
  }
@@ -334,18 +353,30 @@ class FragmentResourceImpl {
334
353
  componentDisplayName,
335
354
  );
336
355
 
337
- const snapshot =
338
- fragmentSelector.kind === 'PluralReaderSelector'
339
- ? fragmentSelector.selectors.map(s => environment.lookup(s))
340
- : environment.lookup(fragmentSelector);
356
+ let fragmentResult = null;
357
+ let snapshot = null;
358
+ // Fall through to existing logic if it's 'missing' state so it would check and save promise into cache.
359
+ if (
360
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
361
+ cachedValue != null &&
362
+ cachedValue.kind === 'missing'
363
+ ) {
364
+ fragmentResult = cachedValue.result;
365
+ snapshot = cachedValue.snapshot;
366
+ } else {
367
+ snapshot =
368
+ fragmentSelector.kind === 'PluralReaderSelector'
369
+ ? fragmentSelector.selectors.map(s => environment.lookup(s))
370
+ : environment.lookup(fragmentSelector);
341
371
 
342
- const fragmentResult = getFragmentResult(
343
- fragmentIdentifier,
344
- snapshot,
345
- storeEpoch,
346
- );
372
+ fragmentResult = getFragmentResult(
373
+ fragmentIdentifier,
374
+ snapshot,
375
+ storeEpoch,
376
+ );
377
+ }
347
378
  if (!fragmentResult.isMissingData) {
348
- this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
379
+ this._throwOrLogErrorsInSnapshot(snapshot);
349
380
 
350
381
  this._cache.set(fragmentIdentifier, {
351
382
  kind: 'done',
@@ -469,7 +500,30 @@ class FragmentResourceImpl {
469
500
  }
470
501
  }
471
502
 
472
- this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
503
+ // set it as done if has missing data and no pending operations
504
+ if (
505
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
506
+ fragmentResult.isMissingData
507
+ ) {
508
+ this._cache.set(fragmentIdentifier, {
509
+ kind: 'done',
510
+ result: fragmentResult,
511
+ });
512
+ }
513
+
514
+ this._throwOrLogErrorsInSnapshot(snapshot);
515
+
516
+ // At this point, there's nothing we can do. We don't have all the expected
517
+ // data, but there's no indication the missing data will be fulfilled. So we
518
+ // choose to return potentially non-typesafe data. The data returned here
519
+ // might not match the generated types for this fragment/operation.
520
+ environment.__log({
521
+ name: 'fragmentresource.missing_data',
522
+ data: fragmentResult.data,
523
+ fragment: fragmentNode,
524
+ isRelayHooks: true,
525
+ cached: false,
526
+ });
473
527
  return getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
474
528
  }
475
529
 
@@ -505,7 +559,7 @@ class FragmentResourceImpl {
505
559
  };
506
560
  }
507
561
 
508
- _handlePotentialSnapshotErrorsInSnapshot(snapshot: SingularOrPluralSnapshot) {
562
+ _throwOrLogErrorsInSnapshot(snapshot: SingularOrPluralSnapshot) {
509
563
  if (Array.isArray(snapshot)) {
510
564
  snapshot.forEach(s => {
511
565
  handlePotentialSnapshotErrors(
@@ -591,10 +645,26 @@ class FragmentResourceImpl {
591
645
  disposables.push(
592
646
  environment.subscribe(currentSnapshot, latestSnapshot => {
593
647
  const storeEpoch = environment.getStore().getEpoch();
594
- this._cache.set(cacheKey, {
595
- kind: 'done',
596
- result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch),
597
- });
648
+ const result = getFragmentResult(
649
+ cacheKey,
650
+ latestSnapshot,
651
+ storeEpoch,
652
+ );
653
+ if (
654
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
655
+ result.isMissingData
656
+ ) {
657
+ this._cache.set(cacheKey, {
658
+ kind: 'missing',
659
+ result: result,
660
+ snapshot: latestSnapshot,
661
+ });
662
+ } else {
663
+ this._cache.set(cacheKey, {
664
+ kind: 'done',
665
+ result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch),
666
+ });
667
+ }
598
668
  callback();
599
669
  }),
600
670
  );
@@ -670,10 +740,26 @@ class FragmentResourceImpl {
670
740
  // Only update the cache when the data is changed to avoid
671
741
  // returning different `data` instances
672
742
  if (didMissUpdates) {
673
- this._cache.set(cacheKey, {
674
- kind: 'done',
675
- result: getFragmentResult(cacheKey, currentSnapshots, storeEpoch),
676
- });
743
+ const result = getFragmentResult(
744
+ cacheKey,
745
+ currentSnapshots,
746
+ storeEpoch,
747
+ );
748
+ if (
749
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
750
+ result.isMissingData
751
+ ) {
752
+ this._cache.set(cacheKey, {
753
+ kind: 'missing',
754
+ result,
755
+ snapshot: currentSnapshots,
756
+ });
757
+ } else {
758
+ this._cache.set(cacheKey, {
759
+ kind: 'done',
760
+ result,
761
+ });
762
+ }
677
763
  }
678
764
  return [didMissUpdates, currentSnapshots];
679
765
  }
@@ -692,10 +778,26 @@ class FragmentResourceImpl {
692
778
  relayResolverErrors: currentSnapshot.relayResolverErrors,
693
779
  };
694
780
  if (updatedData !== renderData) {
695
- this._cache.set(cacheKey, {
696
- kind: 'done',
697
- result: getFragmentResult(cacheKey, updatedCurrentSnapshot, storeEpoch),
698
- });
781
+ const result = getFragmentResult(
782
+ cacheKey,
783
+ updatedCurrentSnapshot,
784
+ storeEpoch,
785
+ );
786
+ if (
787
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
788
+ result.isMissingData
789
+ ) {
790
+ this._cache.set(cacheKey, {
791
+ kind: 'missing',
792
+ result: result,
793
+ snapshot: updatedCurrentSnapshot,
794
+ });
795
+ } else {
796
+ this._cache.set(cacheKey, {
797
+ kind: 'done',
798
+ result,
799
+ });
800
+ }
699
801
  }
700
802
  return [updatedData !== renderData, updatedCurrentSnapshot];
701
803
  }
@@ -736,7 +838,7 @@ class FragmentResourceImpl {
736
838
  .then(() => {
737
839
  this._cache.delete(cacheKey);
738
840
  })
739
- .catch((error: Error) => {
841
+ .catch<void>((error: Error) => {
740
842
  this._cache.delete(cacheKey);
741
843
  });
742
844
  // $FlowExpectedError[prop-missing] Expando to annotate Promises.
@@ -773,10 +875,22 @@ class FragmentResourceImpl {
773
875
  ? [...currentSnapshot]
774
876
  : [...baseSnapshots];
775
877
  nextSnapshots[idx] = latestSnapshot;
776
- this._cache.set(cacheKey, {
777
- kind: 'done',
778
- result: getFragmentResult(cacheKey, nextSnapshots, storeEpoch),
779
- });
878
+ const result = getFragmentResult(cacheKey, nextSnapshots, storeEpoch);
879
+ if (
880
+ RelayFeatureFlags.ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE &&
881
+ result.isMissingData
882
+ ) {
883
+ this._cache.set(cacheKey, {
884
+ kind: 'missing',
885
+ result,
886
+ snapshot: nextSnapshots,
887
+ });
888
+ } else {
889
+ this._cache.set(cacheKey, {
890
+ kind: 'done',
891
+ result,
892
+ });
893
+ }
780
894
  }
781
895
  }
782
896
 
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * @flow strict-local
8
- * @emails oncall+relay
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -4,13 +4,13 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
13
-
13
+ import type {OperationType} from '../../relay-runtime/util/RelayRuntimeTypes';
14
14
  import type {
15
15
  EntryPoint,
16
16
  EntryPointComponent,
@@ -85,8 +85,10 @@ function prepareEntryPoint<
85
85
  }
86
86
  const preloadProps = entryPoint.getPreloadProps(entryPointParams);
87
87
  const {queries, entryPoints, extraProps} = preloadProps;
88
- const preloadedQueries: $Shape<TPreloadedQueries> = {};
89
- const preloadedEntryPoints: $Shape<TPreloadedEntryPoints> = {};
88
+ // $FlowFixMe[incompatible-type]
89
+ const preloadedQueries: Partial<TPreloadedQueries> = {};
90
+ // $FlowFixMe[incompatible-type]
91
+ const preloadedEntryPoints: Partial<TPreloadedEntryPoints> = {};
90
92
  if (queries != null) {
91
93
  const queriesPropNames = Object.keys(queries);
92
94
  queriesPropNames.forEach(queryPropName => {
@@ -97,7 +99,10 @@ function prepareEntryPoint<
97
99
  environmentProviderOptions,
98
100
  );
99
101
 
100
- preloadedQueries[queryPropName] = preloadQuery_DEPRECATED(
102
+ preloadedQueries[queryPropName] = preloadQuery_DEPRECATED<
103
+ OperationType,
104
+ mixed,
105
+ >(
101
106
  environment,
102
107
  parameters,
103
108
  variables,
@@ -116,11 +121,15 @@ function prepareEntryPoint<
116
121
  }
117
122
  const {entryPoint: nestedEntryPoint, entryPointParams: nestedParams} =
118
123
  entryPointDescription;
119
- preloadedEntryPoints[entryPointPropName] = prepareEntryPoint(
120
- environmentProvider,
121
- nestedEntryPoint,
122
- nestedParams,
123
- );
124
+ preloadedEntryPoints[entryPointPropName] = prepareEntryPoint<
125
+ _,
126
+ {...},
127
+ {...},
128
+ {...},
129
+ mixed,
130
+ EntryPointComponent<{...}, {...}, {...}, mixed>,
131
+ _,
132
+ >(environmentProvider, nestedEntryPoint, nestedParams);
124
133
  });
125
134
  }
126
135
  return {
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -0,0 +1,51 @@
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
+ * @format
9
+ * @oncall relay
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ import type {
15
+ InternalEntryPointRepresentation,
16
+ ThinNestedEntryPointParams,
17
+ } from './EntryPointTypes.flow';
18
+
19
+ /**
20
+ * This is an identity function to construct a type safe nested entrypoint.
21
+ * By calling this function, we ensure that the type of entryPointParams matches
22
+ * exactly the type of preloadProps of the entrypoint.
23
+ *
24
+ * We make the type of `ThinNestedEntryPointParams` opaque, so that the only way
25
+ * to construct a `ThinNestedEntryPointParams` is by calling this function.
26
+ */
27
+ declare function NestedRelayEntryPoint<
28
+ TEntryPointParams,
29
+ TPreloadedQueries,
30
+ TPreloadedEntryPoints,
31
+ TRuntimeProps,
32
+ TExtraProps,
33
+ >(
34
+ $ReadOnly<{
35
+ entryPoint: InternalEntryPointRepresentation<
36
+ TEntryPointParams,
37
+ TPreloadedQueries,
38
+ TPreloadedEntryPoints,
39
+ TRuntimeProps,
40
+ TExtraProps,
41
+ >,
42
+ entryPointParams: TEntryPointParams,
43
+ }>,
44
+ ): ThinNestedEntryPointParams;
45
+
46
+ // eslint-disable-next-line no-redeclare
47
+ function NestedRelayEntryPoint<P>(params: P): P {
48
+ return params;
49
+ }
50
+
51
+ export {NestedRelayEntryPoint};
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  // This contextual profiler can be used to wrap a react sub-tree. It will bind
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * @flow strict-local
8
- * @emails oncall+relay
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -35,6 +35,7 @@ const warning = require('warning');
35
35
 
36
36
  const CACHE_CAPACITY = 1000;
37
37
  const DEFAULT_FETCH_POLICY = 'store-or-network';
38
+ const DEFAULT_LIVE_FETCH_POLICY = 'store-and-network';
38
39
 
39
40
  export type QueryResource = QueryResourceImpl;
40
41
 
@@ -83,7 +84,11 @@ function getQueryCacheIdentifier(
83
84
  maybeRenderPolicy: ?RenderPolicy,
84
85
  cacheBreaker?: ?string | ?number,
85
86
  ): string {
86
- const fetchPolicy = maybeFetchPolicy ?? DEFAULT_FETCH_POLICY;
87
+ const fetchPolicy =
88
+ maybeFetchPolicy ??
89
+ (operationIsLiveQuery(operation)
90
+ ? DEFAULT_LIVE_FETCH_POLICY
91
+ : DEFAULT_FETCH_POLICY);
87
92
  const renderPolicy =
88
93
  maybeRenderPolicy ?? environment.UNSTABLE_getDefaultRenderPolicy();
89
94
  const cacheIdentifier = `${fetchPolicy}-${renderPolicy}-${operation.request.identifier}`;
@@ -143,7 +148,18 @@ function createCacheEntry(
143
148
  };
144
149
  });
145
150
 
146
- const cacheEntry = {
151
+ const cacheEntry: {
152
+ cacheIdentifier: string,
153
+ getValue(): QueryResult | Promise<void> | Error,
154
+ id: number,
155
+ operationAvailability: ?OperationAvailability,
156
+ permanentRetain(environment: IEnvironment): Disposable,
157
+ processedPayloadsCount: number,
158
+ releaseTemporaryRetain(): void,
159
+ setNetworkSubscription(subscription: ?Subscription): void,
160
+ setValue(val: QueryResult | Promise<void> | Error): void,
161
+ temporaryRetain(environment: IEnvironment): Disposable,
162
+ } = {
147
163
  cacheIdentifier,
148
164
  id: nextID++,
149
165
  processedPayloadsCount: 0,
@@ -225,7 +241,11 @@ class QueryResourceImpl {
225
241
  profilerContext: mixed,
226
242
  ): QueryResult {
227
243
  const environment = this._environment;
228
- const fetchPolicy = maybeFetchPolicy ?? DEFAULT_FETCH_POLICY;
244
+ const fetchPolicy =
245
+ maybeFetchPolicy ??
246
+ (operationIsLiveQuery(operation)
247
+ ? DEFAULT_LIVE_FETCH_POLICY
248
+ : DEFAULT_FETCH_POLICY);
229
249
  const renderPolicy =
230
250
  maybeRenderPolicy ?? environment.UNSTABLE_getDefaultRenderPolicy();
231
251
 
@@ -525,7 +545,7 @@ class QueryResourceImpl {
525
545
 
526
546
  let cacheEntry = this._cache.get(cacheIdentifier);
527
547
  if (!cacheEntry) {
528
- const networkPromise = new Promise(resolve => {
548
+ const networkPromise = new Promise<void>(resolve => {
529
549
  resolveNetworkPromise = resolve;
530
550
  });
531
551
 
@@ -4,9 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -17,8 +17,8 @@ import type {
17
17
  IActorEnvironment,
18
18
  } from 'relay-runtime/multi-actor-environment';
19
19
 
20
+ const ReactRelayContext = require('./../ReactRelayContext');
20
21
  const React = require('react');
21
- const ReactRelayContext = require('react-relay/ReactRelayContext');
22
22
 
23
23
  const {useMemo} = React;
24
24
 
@@ -5,8 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
7
  * @flow strict-local
8
- * @emails oncall+relay
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
@@ -4,11 +4,13 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
+ /* eslint-disable no-unused-vars */
13
+
12
14
  'use strict';
13
15
 
14
16
  import type {
@@ -4,19 +4,21 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @emails oncall+relay
8
7
  * @flow strict-local
9
8
  * @format
9
+ * @oncall relay
10
10
  */
11
11
 
12
12
  'use strict';
13
13
 
14
- import type {JSResourceReference} from 'JSResourceReference';
15
14
  import type {
16
15
  EntryPoint,
17
16
  EntryPointProps,
18
17
  PreloadedEntryPoint,
19
18
  } from '../../EntryPointTypes.flow';
19
+ import type {JSResourceReference} from 'JSResourceReference';
20
+
21
+ import {NestedRelayEntryPoint} from '../../NestedRelayEntryPointBuilderUtils';
20
22
 
21
23
  declare function mockJSResource<TModule>(
22
24
  module: TModule,
@@ -65,14 +67,14 @@ type BadParentEntrypointParams = $ReadOnly<{}>;
65
67
  getPreloadProps(_params: BadParentEntrypointParams) {
66
68
  return {
67
69
  entryPoints: {
68
- nestedComponent: {
69
- entryPoint: NestedEntryPoint,
70
+ nestedComponent: NestedRelayEntryPoint({
70
71
  /**
71
72
  $FlowExpectedError The entryPointParams here should be of type
72
73
  NestedEntrypointPreloadParams, but it does not contain subEntrypointPreloadParam
73
74
  */
75
+ entryPoint: NestedEntryPoint,
74
76
  entryPointParams: Object.freeze({}),
75
- },
77
+ }),
76
78
  },
77
79
  };
78
80
  },
@@ -90,13 +92,13 @@ type GoodParentEntrypointParams = $ReadOnly<{}>;
90
92
  getPreloadProps(_params: GoodParentEntrypointParams) {
91
93
  return {
92
94
  entryPoints: {
93
- nestedComponent: {
95
+ nestedComponent: NestedRelayEntryPoint({
94
96
  entryPoint: NestedEntryPoint,
95
97
  // No flow error since this matches NestedEntrypointPreloadParams
96
98
  entryPointParams: {
97
99
  subEntrypointPreloadParam: 'test',
98
100
  },
99
- },
101
+ }),
100
102
  },
101
103
  };
102
104
  },
@@ -4,7 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<8a8e68a3fde4da3f77546ac4952f2635>>
7
+ * @oncall relay
8
+ *
9
+ * @generated SignedSource<<fef9e96f393a59b2e761b70b1c3ddc50>>
8
10
  * @flow
9
11
  * @lightSyntaxTransform
10
12
  * @nogrep
@@ -4,7 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  *
7
- * @generated SignedSource<<0b4a6e76a104111de9ddd4dd9abe667c>>
7
+ * @oncall relay
8
+ *
9
+ * @generated SignedSource<<1bd343735be9917826ee3203cf6756c4>>
8
10
  * @flow
9
11
  * @lightSyntaxTransform
10
12
  * @nogrep