react-relay 14.1.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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