react-relay 13.1.1 → 14.1.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 (178) hide show
  1. package/ReactRelayContainerUtils.js.flow +0 -2
  2. package/ReactRelayContext.js +1 -1
  3. package/ReactRelayContext.js.flow +0 -2
  4. package/ReactRelayFragmentContainer.js.flow +7 -6
  5. package/ReactRelayFragmentMockRenderer.js.flow +0 -2
  6. package/ReactRelayLocalQueryRenderer.js.flow +1 -3
  7. package/ReactRelayPaginationContainer.js.flow +13 -10
  8. package/ReactRelayQueryFetcher.js.flow +10 -11
  9. package/ReactRelayQueryRenderer.js.flow +15 -16
  10. package/ReactRelayQueryRendererContext.js.flow +1 -3
  11. package/ReactRelayRefetchContainer.js.flow +10 -7
  12. package/ReactRelayTestMocker.js.flow +0 -2
  13. package/ReactRelayTypes.js.flow +6 -8
  14. package/RelayContext.js.flow +0 -2
  15. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -4
  16. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +3 -5
  17. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +3 -5
  18. package/__flowtests__/RelayModern-flowtest.js.flow +2 -4
  19. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +2 -4
  20. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +2 -4
  21. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +2 -4
  22. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +2 -4
  23. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +2 -2
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +2 -2
  25. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +3 -3
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +3 -3
  27. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +3 -3
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +3 -3
  29. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +2 -2
  30. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +2 -2
  31. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +2 -2
  32. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +2 -2
  33. package/assertFragmentMap.js.flow +0 -2
  34. package/buildReactRelayContainer.js.flow +2 -4
  35. package/getRootVariablesForFragments.js.flow +0 -2
  36. package/hooks.js +1 -1
  37. package/hooks.js.flow +0 -2
  38. package/index.js +1 -1
  39. package/index.js.flow +2 -2
  40. package/isRelayEnvironment.js.flow +0 -2
  41. package/jest-react/internalAct.js.flow +25 -9
  42. package/legacy.js +1 -1
  43. package/legacy.js.flow +0 -2
  44. package/lib/ReactRelayContainerUtils.js +0 -1
  45. package/lib/ReactRelayContext.js +0 -1
  46. package/lib/ReactRelayFragmentContainer.js +10 -9
  47. package/lib/ReactRelayFragmentMockRenderer.js +0 -1
  48. package/lib/ReactRelayLocalQueryRenderer.js +0 -1
  49. package/lib/ReactRelayPaginationContainer.js +14 -11
  50. package/lib/ReactRelayQueryFetcher.js +2 -2
  51. package/lib/ReactRelayQueryRenderer.js +2 -4
  52. package/lib/ReactRelayQueryRendererContext.js +0 -1
  53. package/lib/ReactRelayRefetchContainer.js +11 -14
  54. package/lib/ReactRelayTestMocker.js +1 -2
  55. package/lib/ReactRelayTypes.js +0 -1
  56. package/lib/RelayContext.js +0 -1
  57. package/lib/assertFragmentMap.js +0 -1
  58. package/lib/buildReactRelayContainer.js +1 -2
  59. package/lib/getRootVariablesForFragments.js +1 -2
  60. package/lib/hooks.js +0 -1
  61. package/lib/index.js +3 -1
  62. package/lib/isRelayEnvironment.js +0 -1
  63. package/lib/jest-react/internalAct.js +24 -4
  64. package/lib/legacy.js +0 -1
  65. package/lib/multi-actor/useRelayActorEnvironment.js +0 -1
  66. package/lib/readContext.js +2 -2
  67. package/lib/relay-hooks/EntryPointContainer.react.js +0 -1
  68. package/lib/relay-hooks/EntryPointTypes.flow.js +0 -1
  69. package/lib/relay-hooks/FragmentResource.js +68 -29
  70. package/lib/relay-hooks/HooksImplementation.js +29 -0
  71. package/lib/relay-hooks/InternalLogger.js +0 -1
  72. package/lib/relay-hooks/LRUCache.js +0 -1
  73. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +0 -1
  74. package/lib/relay-hooks/MatchContainer.js +2 -2
  75. package/lib/relay-hooks/ProfilerContext.js +0 -1
  76. package/lib/relay-hooks/QueryResource.js +5 -168
  77. package/lib/relay-hooks/RelayEnvironmentProvider.js +0 -1
  78. package/lib/relay-hooks/SuspenseResource.js +1 -2
  79. package/lib/relay-hooks/loadQuery.js +1 -1
  80. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +8 -13
  81. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +0 -1
  82. package/lib/relay-hooks/react-cache/RelayReactCache.js +36 -0
  83. package/lib/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js +344 -0
  84. package/lib/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js +239 -0
  85. package/lib/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js +598 -0
  86. package/lib/relay-hooks/react-cache/useFragment_REACT_CACHE.js +50 -0
  87. package/lib/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js +55 -0
  88. package/lib/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js +150 -0
  89. package/lib/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js +124 -0
  90. package/lib/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js +367 -0
  91. package/lib/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js +45 -0
  92. package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -3
  93. package/lib/relay-hooks/useClientQuery.js +33 -0
  94. package/lib/relay-hooks/useEntryPointLoader.js +1 -2
  95. package/lib/relay-hooks/useFetchTrackingRef.js +0 -1
  96. package/lib/relay-hooks/useFragment.js +15 -2
  97. package/lib/relay-hooks/useFragmentNode.js +0 -1
  98. package/lib/relay-hooks/useIsMountedRef.js +0 -1
  99. package/lib/relay-hooks/useLazyLoadQuery.js +4 -2
  100. package/lib/relay-hooks/useLazyLoadQueryNode.js +0 -1
  101. package/lib/relay-hooks/useLoadMoreFunction.js +1 -2
  102. package/lib/relay-hooks/useMemoOperationDescriptor.js +0 -1
  103. package/lib/relay-hooks/useMemoVariables.js +0 -1
  104. package/lib/relay-hooks/useMutation.js +5 -7
  105. package/lib/relay-hooks/usePaginationFragment.js +15 -3
  106. package/lib/relay-hooks/usePreloadedQuery.js +4 -2
  107. package/lib/relay-hooks/useQueryLoader.js +1 -2
  108. package/lib/relay-hooks/useRefetchableFragment.js +14 -2
  109. package/lib/relay-hooks/useRefetchableFragmentNode.js +1 -2
  110. package/lib/relay-hooks/useRelayEnvironment.js +0 -1
  111. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +0 -1
  112. package/lib/relay-hooks/useSubscribeToInvalidationState.js +0 -1
  113. package/lib/relay-hooks/useSubscription.js +0 -1
  114. package/multi-actor/useRelayActorEnvironment.js.flow +0 -2
  115. package/package.json +3 -3
  116. package/react-relay-hooks.js +2 -2
  117. package/react-relay-hooks.min.js +2 -2
  118. package/react-relay-legacy.js +2 -2
  119. package/react-relay-legacy.min.js +2 -2
  120. package/react-relay.js +2 -2
  121. package/react-relay.min.js +2 -2
  122. package/readContext.js.flow +1 -2
  123. package/relay-hooks/EntryPointContainer.react.js.flow +2 -4
  124. package/relay-hooks/EntryPointTypes.flow.js.flow +30 -32
  125. package/relay-hooks/FragmentResource.js.flow +80 -37
  126. package/relay-hooks/HooksImplementation.js.flow +43 -0
  127. package/relay-hooks/InternalLogger.js.flow +0 -2
  128. package/relay-hooks/LRUCache.js.flow +0 -2
  129. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +4 -6
  130. package/relay-hooks/MatchContainer.js.flow +11 -6
  131. package/relay-hooks/ProfilerContext.js.flow +0 -2
  132. package/relay-hooks/QueryResource.js.flow +12 -209
  133. package/relay-hooks/RelayEnvironmentProvider.js.flow +2 -4
  134. package/relay-hooks/SuspenseResource.js.flow +0 -2
  135. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +3 -3
  136. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +2 -2
  137. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +2 -2
  138. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +2 -2
  139. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +4 -6
  140. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +0 -2
  141. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +4 -6
  142. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +0 -2
  143. package/relay-hooks/__flowtests__/utils.js.flow +8 -10
  144. package/relay-hooks/loadQuery.js.flow +2 -1
  145. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +11 -20
  146. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +0 -2
  147. package/relay-hooks/react-cache/RelayReactCache.js.flow +40 -0
  148. package/relay-hooks/react-cache/getQueryResultOrFetchQuery_REACT_CACHE.js.flow +430 -0
  149. package/relay-hooks/react-cache/readFragmentInternal_REACT_CACHE.js.flow +297 -0
  150. package/relay-hooks/react-cache/useFragmentInternal_REACT_CACHE.js.flow +599 -0
  151. package/relay-hooks/react-cache/useFragment_REACT_CACHE.js.flow +72 -0
  152. package/relay-hooks/react-cache/useLazyLoadQuery_REACT_CACHE.js.flow +70 -0
  153. package/relay-hooks/react-cache/usePaginationFragment_REACT_CACHE.js.flow +171 -0
  154. package/relay-hooks/react-cache/usePreloadedQuery_REACT_CACHE.js.flow +151 -0
  155. package/relay-hooks/react-cache/useRefetchableFragmentInternal_REACT_CACHE.js.flow +595 -0
  156. package/relay-hooks/react-cache/useRefetchableFragment_REACT_CACHE.js.flow +65 -0
  157. package/relay-hooks/useBlockingPaginationFragment.js.flow +4 -6
  158. package/relay-hooks/useClientQuery.js.flow +39 -0
  159. package/relay-hooks/useEntryPointLoader.js.flow +6 -8
  160. package/relay-hooks/useFetchTrackingRef.js.flow +2 -4
  161. package/relay-hooks/useFragment.js.flow +17 -12
  162. package/relay-hooks/useFragmentNode.js.flow +2 -4
  163. package/relay-hooks/useIsMountedRef.js.flow +1 -3
  164. package/relay-hooks/useLazyLoadQuery.js.flow +17 -5
  165. package/relay-hooks/useLazyLoadQueryNode.js.flow +2 -4
  166. package/relay-hooks/useLoadMoreFunction.js.flow +6 -8
  167. package/relay-hooks/useMemoOperationDescriptor.js.flow +0 -2
  168. package/relay-hooks/useMemoVariables.js.flow +0 -2
  169. package/relay-hooks/useMutation.js.flow +5 -7
  170. package/relay-hooks/usePaginationFragment.js.flow +44 -19
  171. package/relay-hooks/usePreloadedQuery.js.flow +14 -5
  172. package/relay-hooks/useQueryLoader.js.flow +4 -6
  173. package/relay-hooks/useRefetchableFragment.js.flow +32 -3
  174. package/relay-hooks/useRefetchableFragmentNode.js.flow +38 -25
  175. package/relay-hooks/useRelayEnvironment.js.flow +0 -2
  176. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +0 -2
  177. package/relay-hooks/useSubscribeToInvalidationState.js.flow +0 -2
  178. package/relay-hooks/useSubscription.js.flow +14 -10
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  'use strict';
15
13
 
16
14
  import type {Cache} from './LRUCache';
@@ -24,6 +22,7 @@ import type {
24
22
  RequestDescriptor,
25
23
  Snapshot,
26
24
  } from 'relay-runtime';
25
+ import type {MissingLiveResolverField} from 'relay-runtime/store/RelayStoreTypes';
27
26
 
28
27
  const LRUCache = require('./LRUCache');
29
28
  const {getQueryResourceForEnvironment} = require('./QueryResource');
@@ -37,21 +36,21 @@ const {
37
36
  getPendingOperationsForFragment,
38
37
  getSelector,
39
38
  getVariablesFromFragment,
39
+ handlePotentialSnapshotErrors,
40
40
  isPromise,
41
41
  recycleNodesInto,
42
- reportMissingRequiredFields,
43
42
  } = require('relay-runtime');
44
43
 
45
44
  export type FragmentResource = FragmentResourceImpl;
46
45
 
47
46
  type FragmentResourceCache = Cache<
48
- | {|
47
+ | {
49
48
  kind: 'pending',
50
49
  pendingOperations: $ReadOnlyArray<RequestDescriptor>,
51
50
  promise: Promise<mixed>,
52
51
  result: FragmentResult,
53
- |}
54
- | {|kind: 'done', result: FragmentResult|},
52
+ }
53
+ | {kind: 'done', result: FragmentResult},
55
54
  >;
56
55
 
57
56
  const WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
@@ -62,13 +61,13 @@ interface IMap<K, V> {
62
61
 
63
62
  type SingularOrPluralSnapshot = Snapshot | $ReadOnlyArray<Snapshot>;
64
63
 
65
- opaque type FragmentResult: {data: mixed, ...} = {|
64
+ opaque type FragmentResult: {data: mixed, ...} = {
66
65
  cacheKey: string,
67
66
  data: mixed,
68
67
  isMissingData: boolean,
69
68
  snapshot: SingularOrPluralSnapshot | null,
70
69
  storeEpoch: number,
71
- |};
70
+ };
72
71
 
73
72
  // TODO: Fix to not rely on LRU. If the number of active fragments exceeds this
74
73
  // capacity, readSpec() will fail to find cached entries and break object
@@ -92,6 +91,18 @@ function hasMissingClientEdges(snapshot: SingularOrPluralSnapshot): boolean {
92
91
  return (snapshot.missingClientEdges?.length ?? 0) > 0;
93
92
  }
94
93
 
94
+ function missingLiveResolverFields(
95
+ snapshot: SingularOrPluralSnapshot,
96
+ ): ?$ReadOnlyArray<MissingLiveResolverField> {
97
+ if (Array.isArray(snapshot)) {
98
+ return snapshot
99
+ .map(s => s.missingLiveResolverFields)
100
+ .filter(Boolean)
101
+ .flat();
102
+ }
103
+ return snapshot.missingLiveResolverFields;
104
+ }
105
+
95
106
  function singularOrPluralForEach(
96
107
  snapshot: SingularOrPluralSnapshot,
97
108
  f: Snapshot => void,
@@ -165,7 +176,7 @@ class ClientEdgeQueryResultsCache {
165
176
  }
166
177
  }
167
178
 
168
- _retain(id) {
179
+ _retain(id: string): {dispose: () => void} {
169
180
  const retainCount = (this._retainCounts.get(id) ?? 0) + 1;
170
181
  this._retainCounts.set(id, retainCount);
171
182
  return {
@@ -288,8 +299,12 @@ class FragmentResourceImpl {
288
299
  throw cachedValue.promise;
289
300
  }
290
301
 
291
- if (cachedValue.kind === 'done' && cachedValue.result.snapshot) {
292
- this._reportMissingRequiredFieldsInSnapshot(
302
+ if (
303
+ cachedValue.kind === 'done' &&
304
+ cachedValue.result.snapshot &&
305
+ !missingLiveResolverFields(cachedValue.result.snapshot)?.length
306
+ ) {
307
+ this._handlePotentialSnapshotErrorsInSnapshot(
293
308
  cachedValue.result.snapshot,
294
309
  );
295
310
  return cachedValue.result;
@@ -330,7 +345,7 @@ class FragmentResourceImpl {
330
345
  storeEpoch,
331
346
  );
332
347
  if (!fragmentResult.isMissingData) {
333
- this._reportMissingRequiredFieldsInSnapshot(snapshot);
348
+ this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
334
349
 
335
350
  this._cache.set(fragmentIdentifier, {
336
351
  kind: 'done',
@@ -352,6 +367,7 @@ class FragmentResourceImpl {
352
367
  let clientEdgeRequests: ?Array<RequestDescriptor> = null;
353
368
  if (
354
369
  RelayFeatureFlags.ENABLE_CLIENT_EDGES &&
370
+ fragmentNode.metadata?.hasClientEdges === true &&
355
371
  hasMissingClientEdges(snapshot)
356
372
  ) {
357
373
  clientEdgeRequests = [];
@@ -384,11 +400,11 @@ class FragmentResourceImpl {
384
400
  queryResults,
385
401
  );
386
402
  }
387
- let clientEdgePromises = null;
403
+ let clientEdgePromises: Array<Promise<void>> = [];
388
404
  if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && clientEdgeRequests) {
389
405
  clientEdgePromises = clientEdgeRequests
390
406
  .map(request => getPromiseForActiveRequest(this._environment, request))
391
- .filter(p => p != null);
407
+ .filter(Boolean);
392
408
  }
393
409
 
394
410
  // Finally look for operations in flight for our parent query:
@@ -404,9 +420,17 @@ class FragmentResourceImpl {
404
420
  fragmentResult,
405
421
  );
406
422
  const parentQueryPromiseResultPromise = parentQueryPromiseResult?.promise; // for refinement
423
+ const missingResolverFieldPromises =
424
+ missingLiveResolverFields(snapshot)?.map(({liveStateID}) => {
425
+ const store = environment.getStore();
426
+
427
+ // $FlowFixMe[prop-missing] This is expected to be a LiveResolverStore
428
+ return store.getLiveResolverPromise(liveStateID);
429
+ }) ?? [];
407
430
 
408
431
  if (
409
- clientEdgePromises?.length ||
432
+ clientEdgePromises.length ||
433
+ missingResolverFieldPromises.length ||
410
434
  isPromise(parentQueryPromiseResultPromise)
411
435
  ) {
412
436
  environment.__log({
@@ -416,17 +440,36 @@ class FragmentResourceImpl {
416
440
  isRelayHooks: true,
417
441
  isPromiseCached: false,
418
442
  isMissingData: fragmentResult.isMissingData,
443
+ // TODO! Attach information here about missing live resolver fields
419
444
  pendingOperations: [
420
445
  ...(parentQueryPromiseResult?.pendingOperations ?? []),
421
446
  ...(clientEdgeRequests ?? []),
422
447
  ],
423
448
  });
424
- throw clientEdgePromises?.length
425
- ? Promise.all([parentQueryPromiseResultPromise, ...clientEdgePromises])
426
- : parentQueryPromiseResultPromise;
449
+ let promises = [];
450
+ if (clientEdgePromises.length > 0) {
451
+ promises = promises.concat(clientEdgePromises);
452
+ }
453
+ if (missingResolverFieldPromises.length > 0) {
454
+ promises = promises.concat(missingResolverFieldPromises);
455
+ }
456
+
457
+ if (promises.length > 0) {
458
+ if (parentQueryPromiseResultPromise) {
459
+ promises.push(parentQueryPromiseResultPromise);
460
+ }
461
+ throw Promise.all(promises);
462
+ }
463
+
464
+ // Note: we are re-throwing the `parentQueryPromiseResultPromise` here,
465
+ // because some of our suspense-related code is relying on the instance equality
466
+ // of thrown promises. See FragmentResource-test.js
467
+ if (parentQueryPromiseResultPromise) {
468
+ throw parentQueryPromiseResultPromise;
469
+ }
427
470
  }
428
471
 
429
- this._reportMissingRequiredFieldsInSnapshot(snapshot);
472
+ this._handlePotentialSnapshotErrorsInSnapshot(snapshot);
430
473
  return getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
431
474
  }
432
475
 
@@ -436,7 +479,7 @@ class FragmentResourceImpl {
436
479
  fragmentRef: mixed,
437
480
  request: ConcreteRequest,
438
481
  clientEdgeDestinationID: DataID,
439
- ) {
482
+ ): {queryResult: QueryResult, requestDescriptor: RequestDescriptor} {
440
483
  const originalVariables = getVariablesFromFragment(
441
484
  fragmentNode,
442
485
  fragmentRef,
@@ -462,23 +505,21 @@ class FragmentResourceImpl {
462
505
  };
463
506
  }
464
507
 
465
- _reportMissingRequiredFieldsInSnapshot(snapshot: SingularOrPluralSnapshot) {
508
+ _handlePotentialSnapshotErrorsInSnapshot(snapshot: SingularOrPluralSnapshot) {
466
509
  if (Array.isArray(snapshot)) {
467
510
  snapshot.forEach(s => {
468
- if (s.missingRequiredFields != null) {
469
- reportMissingRequiredFields(
470
- this._environment,
471
- s.missingRequiredFields,
472
- );
473
- }
474
- });
475
- } else {
476
- if (snapshot.missingRequiredFields != null) {
477
- reportMissingRequiredFields(
511
+ handlePotentialSnapshotErrors(
478
512
  this._environment,
479
- snapshot.missingRequiredFields,
513
+ s.missingRequiredFields,
514
+ s.relayResolverErrors,
480
515
  );
481
- }
516
+ });
517
+ } else {
518
+ handlePotentialSnapshotErrors(
519
+ this._environment,
520
+ snapshot.missingRequiredFields,
521
+ snapshot.relayResolverErrors,
522
+ );
482
523
  }
483
524
  }
484
525
 
@@ -487,7 +528,7 @@ class FragmentResourceImpl {
487
528
  fragmentRefs: {[string]: mixed, ...},
488
529
  componentDisplayName: string,
489
530
  ): {[string]: FragmentResult, ...} {
490
- const result = {};
531
+ const result: {[string]: FragmentResult} = {};
491
532
  for (const key in fragmentNodes) {
492
533
  result[key] = this.read(
493
534
  fragmentNodes[key],
@@ -596,7 +637,7 @@ class FragmentResourceImpl {
596
637
 
597
638
  checkMissedUpdates(
598
639
  fragmentResult: FragmentResult,
599
- ): [boolean, SingularOrPluralSnapshot | null] {
640
+ ): [boolean /* were updates missed? */, SingularOrPluralSnapshot | null] {
600
641
  const environment = this._environment;
601
642
  const renderedSnapshot = fragmentResult.snapshot;
602
643
  if (!renderedSnapshot) {
@@ -644,9 +685,11 @@ class FragmentResourceImpl {
644
685
  data: updatedData,
645
686
  isMissingData: currentSnapshot.isMissingData,
646
687
  missingClientEdges: currentSnapshot.missingClientEdges,
688
+ missingLiveResolverFields: currentSnapshot.missingLiveResolverFields,
647
689
  seenRecords: currentSnapshot.seenRecords,
648
690
  selector: currentSnapshot.selector,
649
691
  missingRequiredFields: currentSnapshot.missingRequiredFields,
692
+ relayResolverErrors: currentSnapshot.relayResolverErrors,
650
693
  };
651
694
  if (updatedData !== renderData) {
652
695
  this._cache.set(cacheKey, {
@@ -671,10 +714,10 @@ class FragmentResourceImpl {
671
714
  fragmentNode: ReaderFragment,
672
715
  fragmentOwner: RequestDescriptor,
673
716
  fragmentResult: FragmentResult,
674
- ): {|
717
+ ): {
675
718
  promise: Promise<void>,
676
719
  pendingOperations: $ReadOnlyArray<RequestDescriptor>,
677
- |} | null {
720
+ } | null {
678
721
  const pendingOperationsResult = getPendingOperationsForFragment(
679
722
  this._environment,
680
723
  fragmentNode,
@@ -0,0 +1,43 @@
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
+ * @emails oncall+relay
8
+ * @flow strict-local
9
+ * @format
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ import typeof useFragment from './useFragment';
15
+ import type {UsePaginationFragmentType} from './usePaginationFragment';
16
+ import type {UseRefetchableFragmentType} from './useRefetchableFragment';
17
+
18
+ const warning = require('warning');
19
+
20
+ type HooksImplementation = {
21
+ useFragment: useFragment,
22
+ usePaginationFragment: UsePaginationFragmentType,
23
+ useRefetchableFragment: UseRefetchableFragmentType,
24
+ };
25
+
26
+ let implementation: HooksImplementation | null = null;
27
+
28
+ function inject(impl: HooksImplementation): void {
29
+ warning(
30
+ implementation !== null,
31
+ 'Relay HooksImplementation was injected twice.',
32
+ );
33
+ implementation = impl;
34
+ }
35
+
36
+ function get(): HooksImplementation | null {
37
+ return implementation;
38
+ }
39
+
40
+ module.exports = {
41
+ inject,
42
+ get,
43
+ };
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  'use strict';
15
13
 
16
14
  type LogEvent = (eventData: string) => void;
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  'use strict';
15
13
 
16
14
  const invariant = require('invariant');
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  'use strict';
15
13
 
16
14
  import type {
@@ -27,13 +25,13 @@ const React = require('react');
27
25
  const {useContext, useEffect, useMemo} = require('react');
28
26
  const {stableCopy} = require('relay-runtime');
29
27
 
30
- type PreloadedEntryPoint<TEntryPointComponent> = $ReadOnly<{|
28
+ type PreloadedEntryPoint<TEntryPointComponent> = $ReadOnly<{
31
29
  entryPoints: React.ElementConfig<TEntryPointComponent>['entryPoints'],
32
30
  extraProps: React.ElementConfig<TEntryPointComponent>['extraProps'],
33
31
  getComponent: () => TEntryPointComponent,
34
32
  queries: React.ElementConfig<TEntryPointComponent>['queries'],
35
33
  rootModuleID: string,
36
- |}>;
34
+ }>;
37
35
 
38
36
  type EntryPointContainerProps<
39
37
  TEntryPointParams,
@@ -42,7 +40,7 @@ type EntryPointContainerProps<
42
40
  TRuntimeProps,
43
41
  TExtraProps,
44
42
  > = $ReadOnly<
45
- $ReadOnly<{|
43
+ $ReadOnly<{
46
44
  entryPoint: EntryPoint<
47
45
  TEntryPointParams,
48
46
  EntryPointComponent<
@@ -55,7 +53,7 @@ type EntryPointContainerProps<
55
53
  entryPointParams: TEntryPointParams,
56
54
  environmentProvider?: IEnvironmentProvider<EnvironmentProviderOptions>,
57
55
  props: TRuntimeProps,
58
- |}>,
56
+ }>,
59
57
  >;
60
58
 
61
59
  function stableStringify(value: mixed): string {
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  'use strict';
15
13
 
16
14
  const React = require('react');
@@ -87,7 +85,7 @@ const {useMemo} = React;
87
85
 
88
86
  // Note: this type is intentionally non-exact, it is expected that the
89
87
  // object may contain sibling fields.
90
- type TypenameOnlyPointer = {|+__typename: string|};
88
+ type TypenameOnlyPointer = {+__typename: string};
91
89
  export type MatchPointer = {
92
90
  +__fragmentPropName?: ?string,
93
91
  +__module_component?: mixed,
@@ -95,12 +93,12 @@ export type MatchPointer = {
95
93
  ...
96
94
  };
97
95
 
98
- export type MatchContainerProps<TProps: {...}, TFallback: React.Node> = {|
96
+ export type MatchContainerProps<TProps: {...}, TFallback: React.Node> = {
99
97
  +fallback?: ?TFallback,
100
98
  +loader: (module: mixed) => React.AbstractComponent<TProps>,
101
99
  +match: ?MatchPointer | ?TypenameOnlyPointer,
102
100
  +props?: TProps,
103
- |};
101
+ };
104
102
 
105
103
  function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
106
104
  fallback,
@@ -149,7 +147,13 @@ function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
149
147
  // TODO: Perform this transformation in RelayReader so that unchanged
150
148
  // output of subscriptions already has a stable identity.
151
149
  if (__fragmentPropName != null && __id != null && __fragments != null) {
152
- const fragProps = {};
150
+ const fragProps: {
151
+ [string]: {
152
+ __fragmentOwner: $FlowFixMe,
153
+ __fragments: $FlowFixMe,
154
+ __id: string,
155
+ },
156
+ } = {};
153
157
  fragProps[__fragmentPropName] = {__id, __fragments, __fragmentOwner};
154
158
  return fragProps;
155
159
  }
@@ -158,6 +162,7 @@ function MatchContainer<TProps: {...}, TFallback: React.Node | null>({
158
162
 
159
163
  if (LoadedContainer != null && fragmentProps != null) {
160
164
  // $FlowFixMe[incompatible-type]
165
+ // $FlowFixMe[cannot-spread-indexer]
161
166
  return <LoadedContainer {...props} {...fragmentProps} />;
162
167
  } else {
163
168
  return fallback ?? null;
@@ -9,8 +9,6 @@
9
9
  * @format
10
10
  */
11
11
 
12
- // flowlint ambiguous-object-type:error
13
-
14
12
  // This contextual profiler can be used to wrap a react sub-tree. It will bind
15
13
  // the RelayProfiler during the render phase of these components. Allows
16
14
  // collecting metrics for a specific part of your application.