react-relay 11.0.1 → 13.0.0-rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayContext.js.flow +2 -3
  3. package/ReactRelayFragmentContainer.js.flow +24 -24
  4. package/ReactRelayFragmentMockRenderer.js.flow +1 -1
  5. package/ReactRelayLocalQueryRenderer.js.flow +6 -7
  6. package/ReactRelayPaginationContainer.js.flow +111 -58
  7. package/ReactRelayQueryFetcher.js.flow +9 -10
  8. package/ReactRelayQueryRenderer.js.flow +115 -81
  9. package/ReactRelayRefetchContainer.js.flow +41 -38
  10. package/ReactRelayTestMocker.js.flow +16 -14
  11. package/ReactRelayTypes.js.flow +10 -10
  12. package/RelayContext.js.flow +3 -3
  13. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +1 -2
  14. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +11 -7
  15. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +10 -6
  16. package/__flowtests__/RelayModern-flowtest.js.flow +78 -46
  17. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +5 -4
  18. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +5 -4
  19. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +4 -3
  20. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +4 -3
  21. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +72 -0
  22. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +72 -0
  23. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +227 -0
  24. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +164 -0
  25. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +227 -0
  26. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +164 -0
  27. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +66 -0
  28. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +66 -0
  29. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +59 -0
  30. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +61 -0
  31. package/assertFragmentMap.js.flow +2 -2
  32. package/buildReactRelayContainer.js.flow +15 -12
  33. package/getRootVariablesForFragments.js.flow +2 -4
  34. package/hooks.js +1 -1
  35. package/hooks.js.flow +5 -6
  36. package/index.js +1 -1
  37. package/index.js.flow +6 -7
  38. package/jest-react/enqueueTask.js.flow +56 -0
  39. package/jest-react/index.js.flow +12 -0
  40. package/jest-react/internalAct.js.flow +139 -0
  41. package/legacy.js +1 -1
  42. package/lib/ReactRelayFragmentContainer.js +21 -15
  43. package/lib/ReactRelayFragmentMockRenderer.js +2 -2
  44. package/lib/ReactRelayLocalQueryRenderer.js +7 -8
  45. package/lib/ReactRelayPaginationContainer.js +96 -38
  46. package/lib/ReactRelayQueryFetcher.js +3 -3
  47. package/lib/ReactRelayQueryRenderer.js +86 -53
  48. package/lib/ReactRelayRefetchContainer.js +38 -25
  49. package/lib/ReactRelayTestMocker.js +8 -9
  50. package/lib/RelayContext.js +3 -2
  51. package/lib/assertFragmentMap.js +3 -2
  52. package/lib/buildReactRelayContainer.js +14 -11
  53. package/lib/getRootVariablesForFragments.js +1 -2
  54. package/lib/hooks.js +5 -5
  55. package/lib/index.js +7 -7
  56. package/lib/jest-react/enqueueTask.js +53 -0
  57. package/lib/jest-react/index.js +13 -0
  58. package/lib/jest-react/internalAct.js +116 -0
  59. package/lib/multi-actor/ActorChange.js +30 -0
  60. package/lib/multi-actor/index.js +11 -0
  61. package/lib/multi-actor/useRelayActorEnvironment.js +29 -0
  62. package/lib/relay-hooks/EntryPointContainer.react.js +3 -3
  63. package/lib/relay-hooks/FragmentResource.js +347 -92
  64. package/lib/relay-hooks/LRUCache.js +1 -1
  65. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +4 -4
  66. package/lib/relay-hooks/MatchContainer.js +1 -1
  67. package/lib/relay-hooks/QueryResource.js +172 -29
  68. package/lib/relay-hooks/RelayEnvironmentProvider.js +5 -3
  69. package/lib/relay-hooks/SuspenseResource.js +130 -0
  70. package/lib/relay-hooks/loadQuery.js +42 -20
  71. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +24 -15
  72. package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -5
  73. package/lib/relay-hooks/useEntryPointLoader.js +2 -2
  74. package/lib/relay-hooks/useFetchTrackingRef.js +2 -1
  75. package/lib/relay-hooks/useFragment.js +8 -7
  76. package/lib/relay-hooks/useFragmentNode.js +4 -4
  77. package/lib/relay-hooks/useIsOperationNodeActive.js +3 -3
  78. package/lib/relay-hooks/useLazyLoadQuery.js +3 -3
  79. package/lib/relay-hooks/useLazyLoadQueryNode.js +10 -4
  80. package/lib/relay-hooks/useLoadMoreFunction.js +8 -12
  81. package/lib/relay-hooks/useMemoOperationDescriptor.js +2 -2
  82. package/lib/relay-hooks/useMemoVariables.js +2 -2
  83. package/lib/relay-hooks/useMutation.js +17 -6
  84. package/lib/relay-hooks/usePaginationFragment.js +2 -3
  85. package/lib/relay-hooks/usePreloadedQuery.js +8 -7
  86. package/lib/relay-hooks/useQueryLoader.js +30 -10
  87. package/lib/relay-hooks/useRefetchableFragmentNode.js +13 -17
  88. package/lib/relay-hooks/useRelayEnvironment.js +3 -3
  89. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -2
  90. package/lib/relay-hooks/useSubscribeToInvalidationState.js +2 -1
  91. package/lib/relay-hooks/useSubscription.js +10 -7
  92. package/multi-actor/ActorChange.js.flow +58 -0
  93. package/multi-actor/index.js.flow +14 -0
  94. package/multi-actor/useRelayActorEnvironment.js.flow +49 -0
  95. package/package.json +3 -2
  96. package/react-relay-hooks.js +2 -2
  97. package/react-relay-hooks.min.js +2 -2
  98. package/react-relay-legacy.js +2 -2
  99. package/react-relay-legacy.min.js +2 -2
  100. package/react-relay.js +2 -2
  101. package/react-relay.min.js +2 -2
  102. package/relay-hooks/EntryPointContainer.react.js.flow +8 -15
  103. package/relay-hooks/EntryPointTypes.flow.js.flow +24 -25
  104. package/relay-hooks/FragmentResource.js.flow +368 -94
  105. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +32 -46
  106. package/relay-hooks/MatchContainer.js.flow +3 -2
  107. package/relay-hooks/QueryResource.js.flow +216 -25
  108. package/relay-hooks/RelayEnvironmentProvider.js.flow +14 -4
  109. package/relay-hooks/SuspenseResource.js.flow +115 -0
  110. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +4 -3
  111. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +1 -1
  112. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +10 -9
  113. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +8 -7
  114. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +10 -9
  115. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +10 -9
  116. package/relay-hooks/__flowtests__/utils.js.flow +8 -12
  117. package/relay-hooks/loadEntryPoint.js.flow +6 -12
  118. package/relay-hooks/loadQuery.js.flow +49 -31
  119. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +30 -21
  120. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +6 -12
  121. package/relay-hooks/useBlockingPaginationFragment.js.flow +13 -11
  122. package/relay-hooks/useEntryPointLoader.js.flow +7 -10
  123. package/relay-hooks/useFetchTrackingRef.js.flow +2 -2
  124. package/relay-hooks/useFragment.js.flow +26 -46
  125. package/relay-hooks/useFragmentNode.js.flow +5 -7
  126. package/relay-hooks/useIsOperationNodeActive.js.flow +3 -5
  127. package/relay-hooks/useIsParentQueryActive.js.flow +3 -4
  128. package/relay-hooks/useLazyLoadQuery.js.flow +9 -10
  129. package/relay-hooks/useLazyLoadQueryNode.js.flow +19 -13
  130. package/relay-hooks/useLoadMoreFunction.js.flow +20 -29
  131. package/relay-hooks/useMemoOperationDescriptor.js.flow +5 -7
  132. package/relay-hooks/useMemoVariables.js.flow +6 -6
  133. package/relay-hooks/useMutation.js.flow +26 -26
  134. package/relay-hooks/usePaginationFragment.js.flow +38 -44
  135. package/relay-hooks/usePreloadedQuery.js.flow +18 -14
  136. package/relay-hooks/useQueryLoader.js.flow +41 -22
  137. package/relay-hooks/useRefetchableFragment.js.flow +7 -8
  138. package/relay-hooks/useRefetchableFragmentNode.js.flow +24 -32
  139. package/relay-hooks/useRelayEnvironment.js.flow +2 -4
  140. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +2 -3
  141. package/relay-hooks/useSubscribeToInvalidationState.js.flow +3 -6
  142. package/relay-hooks/useSubscription.js.flow +20 -10
  143. package/lib/relay-hooks/getPaginationMetadata.js +0 -41
  144. package/lib/relay-hooks/getPaginationVariables.js +0 -67
  145. package/lib/relay-hooks/getRefetchMetadata.js +0 -36
  146. package/lib/relay-hooks/getValueAtPath.js +0 -51
  147. package/relay-hooks/getPaginationMetadata.js.flow +0 -74
  148. package/relay-hooks/getPaginationVariables.js.flow +0 -110
  149. package/relay-hooks/getRefetchMetadata.js.flow +0 -80
  150. package/relay-hooks/getValueAtPath.js.flow +0 -46
@@ -24,40 +24,40 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
24
24
 
25
25
  var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
26
26
 
27
- var React = require('react');
28
-
29
- var ReactRelayContext = require('./ReactRelayContext');
30
-
31
- var ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
32
-
33
- var areEqual = require("fbjs/lib/areEqual");
34
-
35
27
  var buildReactRelayContainer = require('./buildReactRelayContainer');
36
28
 
37
29
  var getRootVariablesForFragments = require('./getRootVariablesForFragments');
38
30
 
39
- var invariant = require("fbjs/lib/invariant");
40
-
41
- var warning = require("fbjs/lib/warning");
42
-
43
31
  var _require = require('./ReactRelayContainerUtils'),
44
32
  getComponentName = _require.getComponentName,
45
33
  getContainerName = _require.getContainerName;
46
34
 
35
+ var ReactRelayContext = require('./ReactRelayContext');
36
+
37
+ var ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
38
+
47
39
  var _require2 = require('./RelayContext'),
48
40
  assertRelayContext = _require2.assertRelayContext;
49
41
 
42
+ var areEqual = require("fbjs/lib/areEqual");
43
+
44
+ var invariant = require('invariant');
45
+
46
+ var React = require('react');
47
+
50
48
  var _require3 = require('relay-runtime'),
51
49
  ConnectionInterface = _require3.ConnectionInterface,
52
50
  Observable = _require3.Observable,
51
+ RelayFeatureFlags = _require3.RelayFeatureFlags,
53
52
  createFragmentSpecResolver = _require3.createFragmentSpecResolver,
54
53
  createOperationDescriptor = _require3.createOperationDescriptor,
55
54
  getDataIDsFromObject = _require3.getDataIDsFromObject,
56
55
  getRequest = _require3.getRequest,
57
- getSelector = _require3.getSelector,
58
56
  getVariablesFromObject = _require3.getVariablesFromObject,
59
57
  isScalarAndEqual = _require3.isScalarAndEqual;
60
58
 
59
+ var warning = require("fbjs/lib/warning");
60
+
61
61
  var FORWARD = 'forward';
62
62
 
63
63
  /**
@@ -211,8 +211,7 @@ function createGetConnectionFromProps(metadata) {
211
211
 
212
212
  function createGetFragmentVariables(metadata) {
213
213
  var countVariable = metadata.count;
214
- !countVariable ? process.env.NODE_ENV !== "production" ? invariant(false, 'ReactRelayPaginationContainer: Unable to synthesize a ' + 'getFragmentVariables function.') : invariant(false) : void 0; // $FlowFixMe[cannot-spread-interface]
215
-
214
+ !countVariable ? process.env.NODE_ENV !== "production" ? invariant(false, 'ReactRelayPaginationContainer: Unable to synthesize a ' + 'getFragmentVariables function.') : invariant(false) : void 0;
216
215
  return function (prevVars, totalCount) {
217
216
  return (0, _objectSpread3["default"])((0, _objectSpread3["default"])({}, prevVars), {}, (0, _defineProperty2["default"])({}, countVariable, totalCount));
218
217
  };
@@ -354,12 +353,19 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
354
353
  _this._isARequestInFlight = false;
355
354
  _this._refetchSubscription = null;
356
355
  _this._refetchVariables = null;
357
- _this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, props, rootIsQueryRenderer, _this._handleFragmentDataUpdate);
356
+
357
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
358
+ _this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, props, rootIsQueryRenderer);
359
+ } else {
360
+ _this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, props, rootIsQueryRenderer, _this._handleFragmentDataUpdate);
361
+ }
362
+
358
363
  _this.state = {
359
364
  data: _this._resolver.resolve(),
360
365
  prevContext: relayContext,
361
366
  contextForChildren: relayContext,
362
- relayProp: _this._buildRelayProp(relayContext)
367
+ relayProp: _this._buildRelayProp(relayContext),
368
+ resolverGeneration: 0
363
369
  };
364
370
  _this._isUnmounted = false;
365
371
  _this._hasFetched = false;
@@ -370,6 +376,20 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
370
376
 
371
377
  _proto.componentDidMount = function componentDidMount() {
372
378
  this._isUnmounted = false;
379
+
380
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
381
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
382
+ }
383
+ };
384
+
385
+ _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
386
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
387
+ if (prevState.resolverGeneration !== this.state.resolverGeneration) {
388
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
389
+ } else {
390
+ this._rerenderIfStoreHasChanged();
391
+ }
392
+ }
373
393
  }
374
394
  /**
375
395
  * When new props are received, read data for the new props and subscribe
@@ -379,6 +399,8 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
379
399
  ;
380
400
 
381
401
  _proto.UNSAFE_componentWillReceiveProps = function UNSAFE_componentWillReceiveProps(nextProps) {
402
+ var _this2 = this;
403
+
382
404
  var _nextProps$__rootIsQu;
383
405
 
384
406
  var relayContext = assertRelayContext(nextProps.__relayContext);
@@ -396,11 +418,19 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
396
418
  this._cleanup(); // Child containers rely on context.relay being mutated (for gDSFP).
397
419
 
398
420
 
399
- this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, nextProps, rootIsQueryRenderer, this._handleFragmentDataUpdate);
400
- this.setState({
401
- prevContext: relayContext,
402
- contextForChildren: relayContext,
403
- relayProp: this._buildRelayProp(relayContext)
421
+ if (RelayFeatureFlags.ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT === true) {
422
+ this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, nextProps, rootIsQueryRenderer);
423
+ } else {
424
+ this._resolver = createFragmentSpecResolver(relayContext, containerName, fragments, nextProps, rootIsQueryRenderer, this._handleFragmentDataUpdate);
425
+ }
426
+
427
+ this.setState(function (prevState) {
428
+ return {
429
+ prevContext: relayContext,
430
+ contextForChildren: relayContext,
431
+ relayProp: _this2._buildRelayProp(relayContext),
432
+ resolverGeneration: prevState.resolverGeneration + 1
433
+ };
404
434
  });
405
435
  } else if (!this._hasFetched) {
406
436
  this._resolver.setProps(nextProps);
@@ -423,7 +453,7 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
423
453
 
424
454
  _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
425
455
  // Short-circuit if any Relay-related data has changed
426
- if (nextState.data !== this.state.data || nextState.relayProp !== this.state.relayProp) {
456
+ if (nextState.data !== this.state.data || nextState.relayProp !== this.state.relayProp || nextState.resolverGeneration !== this.state.resolverGeneration) {
427
457
  return true;
428
458
  } // Otherwise, for convenience short-circuit if all non-Relay props
429
459
  // are scalar and equal
@@ -456,6 +486,37 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
456
486
  refetchConnection: this._refetchConnection,
457
487
  environment: relayContext.environment
458
488
  };
489
+ };
490
+
491
+ _proto._rerenderIfStoreHasChanged = function _rerenderIfStoreHasChanged() {
492
+ var data = this.state.data; // External values could change between render and commit.
493
+ // Check for this case, even though it requires an extra store read.
494
+
495
+ var maybeNewData = this._resolver.resolve();
496
+
497
+ if (data !== maybeNewData) {
498
+ this.setState({
499
+ data: maybeNewData
500
+ });
501
+ }
502
+ };
503
+
504
+ _proto._subscribeToNewResolverAndRerenderIfStoreHasChanged = function _subscribeToNewResolverAndRerenderIfStoreHasChanged() {
505
+ var data = this.state.data;
506
+
507
+ var maybeNewData = this._resolver.resolve(); // Event listeners are only safe to add during the commit phase,
508
+ // So they won't leak if render is interrupted or errors.
509
+
510
+
511
+ this._resolver.setCallback(this.props, this._handleFragmentDataUpdate); // External values could change between render and commit.
512
+ // Check for this case, even though it requires an extra store read.
513
+
514
+
515
+ if (data !== maybeNewData) {
516
+ this.setState({
517
+ data: maybeNewData
518
+ });
519
+ }
459
520
  }
460
521
  /**
461
522
  * Render new data for the existing props/context.
@@ -525,7 +586,7 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
525
586
  };
526
587
 
527
588
  _proto._fetchPage = function _fetchPage(paginatingVariables, observer, options) {
528
- var _this2 = this;
589
+ var _this3 = this;
529
590
 
530
591
  var _assertRelayContext = assertRelayContext(this.props.__relayContext),
531
592
  environment = _assertRelayContext.environment;
@@ -537,17 +598,14 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
537
598
  restProps = (0, _objectWithoutPropertiesLoose2["default"])(_this$props2, ["componentRef", "__relayContext", "__rootIsQueryRenderer"]);
538
599
  var props = (0, _objectSpread3["default"])((0, _objectSpread3["default"])({}, restProps), this.state.data);
539
600
  var fragmentVariables;
540
- var rootVariables = getRootVariablesForFragments(fragments, restProps); // $FlowFixMe[cannot-spread-interface]
541
-
542
- fragmentVariables = getVariablesFromObject(fragments, restProps); // $FlowFixMe[cannot-spread-interface]
543
-
601
+ var rootVariables = getRootVariablesForFragments(fragments, restProps);
602
+ fragmentVariables = getVariablesFromObject(fragments, restProps);
544
603
  fragmentVariables = (0, _objectSpread3["default"])((0, _objectSpread3["default"])((0, _objectSpread3["default"])({}, rootVariables), fragmentVariables), this._refetchVariables);
545
604
  var fetchVariables = connectionConfig.getVariables(props, {
546
605
  count: paginatingVariables.count,
547
606
  cursor: paginatingVariables.cursor
548
607
  }, fragmentVariables);
549
- !(typeof fetchVariables === 'object' && fetchVariables !== null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'ReactRelayPaginationContainer: Expected `getVariables()` to ' + 'return an object, got `%s` in `%s`.', fetchVariables, componentName) : invariant(false) : void 0; // $FlowFixMe[cannot-spread-interface]
550
-
608
+ !(typeof fetchVariables === 'object' && fetchVariables !== null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'ReactRelayPaginationContainer: Expected `getVariables()` to ' + 'return an object, got `%s` in `%s`.', fetchVariables, componentName) : invariant(false) : void 0;
551
609
  fetchVariables = (0, _objectSpread3["default"])((0, _objectSpread3["default"])({}, fetchVariables), this._refetchVariables);
552
610
  fragmentVariables = (0, _objectSpread3["default"])((0, _objectSpread3["default"])({}, fetchVariables), fragmentVariables);
553
611
  var cacheConfig = options ? {
@@ -569,11 +627,11 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
569
627
  this._hasFetched = true;
570
628
 
571
629
  var onNext = function onNext(payload, complete) {
572
- var prevData = _this2._resolver.resolve();
630
+ var prevData = _this3._resolver.resolve();
573
631
 
574
- _this2._resolver.setVariables(getFragmentVariables(fragmentVariables, paginatingVariables.totalCount), operation.request.node);
632
+ _this3._resolver.setVariables(getFragmentVariables(fragmentVariables, paginatingVariables.totalCount), operation.request.node);
575
633
 
576
- var nextData = _this2._resolver.resolve(); // Workaround slightly different handling for connection in different
634
+ var nextData = _this3._resolver.resolve(); // Workaround slightly different handling for connection in different
577
635
  // core implementations:
578
636
  // - Classic core requires the count to be explicitly incremented
579
637
  // - Modern core automatically appends new items, updating the count
@@ -585,10 +643,10 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
585
643
 
586
644
 
587
645
  if (!areEqual(prevData, nextData)) {
588
- _this2.setState({
646
+ _this3.setState({
589
647
  data: nextData,
590
648
  contextForChildren: {
591
- environment: _this2.props.__relayContext.environment
649
+ environment: _this3.props.__relayContext.environment
592
650
  }
593
651
  }, complete);
594
652
  } else {
@@ -597,9 +655,9 @@ function createContainerWithFragments(Component, fragments, connectionConfig) {
597
655
  };
598
656
 
599
657
  var cleanup = function cleanup() {
600
- if (_this2._refetchSubscription === refetchSubscription) {
601
- _this2._refetchSubscription = null;
602
- _this2._isARequestInFlight = false;
658
+ if (_this3._refetchSubscription === refetchSubscription) {
659
+ _this3._refetchSubscription = null;
660
+ _this3._isARequestInFlight = false;
603
661
  }
604
662
  };
605
663
 
@@ -14,12 +14,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
14
14
 
15
15
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
16
16
 
17
- var invariant = require("fbjs/lib/invariant");
17
+ var invariant = require('invariant');
18
18
 
19
19
  var _require = require('relay-runtime'),
20
+ fetchQuery = _require.__internal.fetchQuery,
20
21
  createOperationDescriptor = _require.createOperationDescriptor,
21
- isRelayModernEnvironment = _require.isRelayModernEnvironment,
22
- fetchQuery = _require.__internal.fetchQuery;
22
+ isRelayModernEnvironment = _require.isRelayModernEnvironment;
23
23
 
24
24
  var ReactRelayQueryFetcher = /*#__PURE__*/function () {
25
25
  function ReactRelayQueryFetcher(args) {
@@ -14,9 +14,11 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
14
14
 
15
15
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
16
16
 
17
+ var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
18
+
17
19
  var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
18
20
 
19
- var React = require('react');
21
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
20
22
 
21
23
  var ReactRelayContext = require('./ReactRelayContext');
22
24
 
@@ -26,7 +28,10 @@ var ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext')
26
28
 
27
29
  var areEqual = require("fbjs/lib/areEqual");
28
30
 
31
+ var React = require('react');
32
+
29
33
  var _require = require('relay-runtime'),
34
+ RelayFeatureFlags = _require.RelayFeatureFlags,
30
35
  createOperationDescriptor = _require.createOperationDescriptor,
31
36
  deepFreeze = _require.deepFreeze,
32
37
  getRequest = _require.getRequest;
@@ -64,6 +69,29 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
64
69
  // that reason, we define them as null initially and fill them in after
65
70
  // mounting to avoid leaking memory.
66
71
 
72
+ (0, _defineProperty2["default"])((0, _assertThisInitialized2["default"])(_this), "_handleDataChange", function (params) {
73
+ var error = params.error == null ? null : params.error;
74
+ var snapshot = params.snapshot == null ? null : params.snapshot;
75
+
76
+ _this.setState(function (prevState) {
77
+ var prevRequestCacheKey = prevState.requestCacheKey;
78
+
79
+ if (prevRequestCacheKey) {
80
+ delete requestCache[prevRequestCacheKey];
81
+ } // Don't update state if nothing has changed.
82
+
83
+
84
+ if (snapshot === prevState.snapshot && error === prevState.error) {
85
+ return null;
86
+ }
87
+
88
+ return {
89
+ renderProps: getRenderProps(error, snapshot, prevState.queryFetcher, prevState.retryCallbacks),
90
+ snapshot: snapshot,
91
+ requestCacheKey: null
92
+ };
93
+ });
94
+ });
67
95
  var retryCallbacks = {
68
96
  handleDataChange: null,
69
97
  handleRetryAfterError: null
@@ -80,6 +108,7 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
80
108
  queryFetcher = new ReactRelayQueryFetcher();
81
109
  }
82
110
 
111
+ _this._maybeHiddenOrFastRefresh = false;
83
112
  _this.state = (0, _objectSpread2["default"])({
84
113
  prevPropsEnvironment: props.environment,
85
114
  prevPropsVariables: props.variables,
@@ -92,27 +121,7 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
92
121
 
93
122
  ReactRelayQueryRenderer.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) {
94
123
  if (prevState.prevQuery !== nextProps.query || prevState.prevPropsEnvironment !== nextProps.environment || !areEqual(prevState.prevPropsVariables, nextProps.variables)) {
95
- var query = nextProps.query;
96
- var prevSelectionReferences = prevState.queryFetcher.getSelectionReferences();
97
- prevState.queryFetcher.disposeRequest();
98
- var queryFetcher;
99
-
100
- if (query) {
101
- var request = getRequest(query);
102
- var requestCacheKey = getRequestCacheKey(request.params, nextProps.variables);
103
- queryFetcher = requestCache[requestCacheKey] ? requestCache[requestCacheKey].queryFetcher : new ReactRelayQueryFetcher(prevSelectionReferences);
104
- } else {
105
- queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
106
- }
107
-
108
- return (0, _objectSpread2["default"])({
109
- prevQuery: nextProps.query,
110
- prevPropsEnvironment: nextProps.environment,
111
- prevPropsVariables: nextProps.variables,
112
- queryFetcher: queryFetcher
113
- }, fetchQueryAndComputeStateFromProps(nextProps, queryFetcher, prevState.retryCallbacks // passing no requestCacheKey will cause it to be recalculated internally
114
- // and we want the updated requestCacheKey, since variables may have changed
115
- ));
124
+ return resetQueryStateForUpdate(nextProps, prevState);
116
125
  }
117
126
 
118
127
  return null;
@@ -123,38 +132,31 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
123
132
  _proto.componentDidMount = function componentDidMount() {
124
133
  var _this2 = this;
125
134
 
135
+ if (RelayFeatureFlags.ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT === true && this._maybeHiddenOrFastRefresh === true) {
136
+ // This block only runs if the component has previously "unmounted"
137
+ // due to it being hidden by the Offscreen API, or during fast refresh.
138
+ // At this point, the current cached resource will have been disposed
139
+ // by the previous cleanup, so instead of attempting to
140
+ // do our regular commit setup, so that the query is re-evaluated
141
+ // (and potentially cause a refetch).
142
+ this._maybeHiddenOrFastRefresh = false; // eslint-disable-next-line react/no-did-mount-set-state
143
+
144
+ this.setState(function (prevState) {
145
+ return resetQueryStateForUpdate(_this2.props, prevState);
146
+ });
147
+ return;
148
+ }
149
+
126
150
  var _this$state = this.state,
127
151
  retryCallbacks = _this$state.retryCallbacks,
128
152
  queryFetcher = _this$state.queryFetcher,
129
- requestCacheKey = _this$state.requestCacheKey;
153
+ requestCacheKey = _this$state.requestCacheKey; // We don't need to cache the request after the component commits
130
154
 
131
155
  if (requestCacheKey) {
132
156
  delete requestCache[requestCacheKey];
133
157
  }
134
158
 
135
- retryCallbacks.handleDataChange = function (params) {
136
- var error = params.error == null ? null : params.error;
137
- var snapshot = params.snapshot == null ? null : params.snapshot;
138
-
139
- _this2.setState(function (prevState) {
140
- var prevRequestCacheKey = prevState.requestCacheKey;
141
-
142
- if (prevRequestCacheKey) {
143
- delete requestCache[prevRequestCacheKey];
144
- } // Don't update state if nothing has changed.
145
-
146
-
147
- if (snapshot === prevState.snapshot && error === prevState.error) {
148
- return null;
149
- }
150
-
151
- return {
152
- renderProps: getRenderProps(error, snapshot, prevState.queryFetcher, prevState.retryCallbacks),
153
- snapshot: snapshot,
154
- requestCacheKey: null
155
- };
156
- });
157
- };
159
+ retryCallbacks.handleDataChange = this._handleDataChange;
158
160
 
159
161
  retryCallbacks.handleRetryAfterError = function (error) {
160
162
  return _this2.setState(function (prevState) {
@@ -174,23 +176,30 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
174
176
 
175
177
 
176
178
  if (this.props.query) {
177
- queryFetcher.setOnDataChange(retryCallbacks.handleDataChange);
179
+ queryFetcher.setOnDataChange(this._handleDataChange);
178
180
  }
179
181
  };
180
182
 
181
- _proto.componentDidUpdate = function componentDidUpdate() {
183
+ _proto.componentDidUpdate = function componentDidUpdate(_prevProps, prevState) {
182
184
  // We don't need to cache the request after the component commits
183
- var requestCacheKey = this.state.requestCacheKey;
185
+ var _this$state2 = this.state,
186
+ queryFetcher = _this$state2.queryFetcher,
187
+ requestCacheKey = _this$state2.requestCacheKey;
184
188
 
185
189
  if (requestCacheKey) {
186
190
  delete requestCache[requestCacheKey]; // HACK
187
191
 
188
192
  delete this.state.requestCacheKey;
189
193
  }
194
+
195
+ if (this.props.query && queryFetcher !== prevState.queryFetcher) {
196
+ queryFetcher.setOnDataChange(this._handleDataChange);
197
+ }
190
198
  };
191
199
 
192
200
  _proto.componentWillUnmount = function componentWillUnmount() {
193
201
  this.state.queryFetcher.dispose();
202
+ this._maybeHiddenOrFastRefresh = true;
194
203
  };
195
204
 
196
205
  _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps, nextState) {
@@ -198,9 +207,9 @@ var ReactRelayQueryRenderer = /*#__PURE__*/function (_React$Component) {
198
207
  };
199
208
 
200
209
  _proto.render = function render() {
201
- var _this$state2 = this.state,
202
- renderProps = _this$state2.renderProps,
203
- relayContext = _this$state2.relayContext; // Note that the root fragment results in `renderProps.props` is already
210
+ var _this$state3 = this.state,
211
+ renderProps = _this$state3.renderProps,
212
+ relayContext = _this$state3.relayContext; // Note that the root fragment results in `renderProps.props` is already
204
213
  // frozen by the store; this call is to freeze the renderProps object and
205
214
  // error property if set.
206
215
 
@@ -263,6 +272,30 @@ function getRequestCacheKey(request, variables) {
263
272
  });
264
273
  }
265
274
 
275
+ function resetQueryStateForUpdate(props, prevState) {
276
+ var query = props.query;
277
+ var prevSelectionReferences = prevState.queryFetcher.getSelectionReferences();
278
+ prevState.queryFetcher.disposeRequest();
279
+ var queryFetcher;
280
+
281
+ if (query) {
282
+ var request = getRequest(query);
283
+ var requestCacheKey = getRequestCacheKey(request.params, props.variables);
284
+ queryFetcher = requestCache[requestCacheKey] ? requestCache[requestCacheKey].queryFetcher : new ReactRelayQueryFetcher(prevSelectionReferences);
285
+ } else {
286
+ queryFetcher = new ReactRelayQueryFetcher(prevSelectionReferences);
287
+ }
288
+
289
+ return (0, _objectSpread2["default"])({
290
+ prevQuery: props.query,
291
+ prevPropsEnvironment: props.environment,
292
+ prevPropsVariables: props.variables,
293
+ queryFetcher: queryFetcher
294
+ }, fetchQueryAndComputeStateFromProps(props, queryFetcher, prevState.retryCallbacks // passing no requestCacheKey will cause it to be recalculated internally
295
+ // and we want the updated requestCacheKey, since variables may have changed
296
+ ));
297
+ }
298
+
266
299
  function fetchQueryAndComputeStateFromProps(props, queryFetcher, retryCallbacks, requestCacheKey) {
267
300
  var environment = props.environment,
268
301
  query = props.query,
@@ -306,7 +339,7 @@ function fetchQueryAndComputeStateFromProps(props, queryFetcher, retryCallbacks,
306
339
  var storeSnapshot = queryFetcher.lookupInStore(genericEnvironment, operation, props.fetchPolicy);
307
340
  var querySnapshot = queryFetcher.fetch({
308
341
  environment: genericEnvironment,
309
- onDataChange: retryCallbacks.handleDataChange,
342
+ onDataChange: null,
310
343
  operation: operation
311
344
  }); // Use network data first, since it may be fresher
312
345
 
@@ -24,36 +24,35 @@ var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inh
24
24
 
25
25
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
26
26
 
27
- var React = require('react');
28
-
29
- var ReactRelayContext = require('./ReactRelayContext');
30
-
31
- var ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
32
-
33
- var areEqual = require("fbjs/lib/areEqual");
34
-
35
27
  var buildReactRelayContainer = require('./buildReactRelayContainer');
36
28
 
37
29
  var getRootVariablesForFragments = require('./getRootVariablesForFragments');
38
30
 
39
- var warning = require("fbjs/lib/warning");
40
-
41
31
  var _require = require('./ReactRelayContainerUtils'),
42
32
  getContainerName = _require.getContainerName;
43
33
 
34
+ var ReactRelayContext = require('./ReactRelayContext');
35
+
36
+ var ReactRelayQueryFetcher = require('./ReactRelayQueryFetcher');
37
+
44
38
  var _require2 = require('./RelayContext'),
45
39
  assertRelayContext = _require2.assertRelayContext;
46
40
 
41
+ var areEqual = require("fbjs/lib/areEqual");
42
+
43
+ var React = require('react');
44
+
47
45
  var _require3 = require('relay-runtime'),
48
46
  Observable = _require3.Observable,
49
47
  createFragmentSpecResolver = _require3.createFragmentSpecResolver,
50
48
  createOperationDescriptor = _require3.createOperationDescriptor,
51
49
  getDataIDsFromObject = _require3.getDataIDsFromObject,
52
50
  getRequest = _require3.getRequest,
53
- getSelector = _require3.getSelector,
54
51
  getVariablesFromObject = _require3.getVariablesFromObject,
55
52
  isScalarAndEqual = _require3.isScalarAndEqual;
56
53
 
54
+ var warning = require("fbjs/lib/warning");
55
+
57
56
  /**
58
57
  * Composes a React component class, returning a new class that intercepts
59
58
  * props, resolving them with the provided fragments and subscribing for
@@ -94,11 +93,9 @@ function createContainerWithFragments(Component, fragments, taggedNode) {
94
93
  environment = _assertRelayContext.environment;
95
94
 
96
95
  var rootVariables = getRootVariablesForFragments(fragments, _this.props);
97
- var fetchVariables = typeof refetchVariables === 'function' ? refetchVariables(_this._getFragmentVariables()) : refetchVariables; // $FlowFixMe[cannot-spread-interface]
98
-
96
+ var fetchVariables = typeof refetchVariables === 'function' ? refetchVariables(_this._getFragmentVariables()) : refetchVariables;
99
97
  fetchVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, rootVariables), fetchVariables);
100
- var fragmentVariables = renderVariables ? // $FlowFixMe[cannot-spread-interface]
101
- (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, fetchVariables), renderVariables) : fetchVariables;
98
+ var fragmentVariables = renderVariables ? (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, fetchVariables), renderVariables) : fetchVariables;
102
99
  var cacheConfig = options ? {
103
100
  force: !!options.force
104
101
  } : undefined;
@@ -215,7 +212,7 @@ function createContainerWithFragments(Component, fragments, taggedNode) {
215
212
  _proto.componentDidMount = function componentDidMount() {
216
213
  this._isUnmounted = false;
217
214
 
218
- this._subscribeToNewResolver();
215
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
219
216
  };
220
217
 
221
218
  _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
@@ -229,7 +226,9 @@ function createContainerWithFragments(Component, fragments, taggedNode) {
229
226
  this._queryFetcher && this._queryFetcher.dispose();
230
227
  this._refetchSubscription && this._refetchSubscription.unsubscribe();
231
228
 
232
- this._subscribeToNewResolver();
229
+ this._subscribeToNewResolverAndRerenderIfStoreHasChanged();
230
+ } else {
231
+ this._rerenderIfStoreHasChanged();
233
232
  }
234
233
  }
235
234
  /**
@@ -321,17 +320,31 @@ function createContainerWithFragments(Component, fragments, taggedNode) {
321
320
  return false;
322
321
  };
323
322
 
324
- _proto._subscribeToNewResolver = function _subscribeToNewResolver() {
323
+ _proto._rerenderIfStoreHasChanged = function _rerenderIfStoreHasChanged() {
325
324
  var _this$state = this.state,
326
325
  data = _this$state.data,
327
- resolver = _this$state.resolver; // Event listeners are only safe to add during the commit phase,
328
- // So they won't leak if render is interrupted or errors.
329
-
330
- resolver.setCallback(this._handleFragmentDataUpdate); // External values could change between render and commit.
326
+ resolver = _this$state.resolver; // External values could change between render and commit.
331
327
  // Check for this case, even though it requires an extra store read.
332
328
 
333
329
  var maybeNewData = resolver.resolve();
334
330
 
331
+ if (data !== maybeNewData) {
332
+ this.setState({
333
+ data: maybeNewData
334
+ });
335
+ }
336
+ };
337
+
338
+ _proto._subscribeToNewResolverAndRerenderIfStoreHasChanged = function _subscribeToNewResolverAndRerenderIfStoreHasChanged() {
339
+ var _this$state2 = this.state,
340
+ data = _this$state2.data,
341
+ resolver = _this$state2.resolver;
342
+ var maybeNewData = resolver.resolve(); // Event listeners are only safe to add during the commit phase,
343
+ // So they won't leak if render is interrupted or errors.
344
+
345
+ resolver.setCallback(this.props, this._handleFragmentDataUpdate); // External values could change between render and commit.
346
+ // Check for this case, even though it requires an extra store read.
347
+
335
348
  if (data !== maybeNewData) {
336
349
  this.setState({
337
350
  data: maybeNewData
@@ -361,9 +374,9 @@ function createContainerWithFragments(Component, fragments, taggedNode) {
361
374
  __relayContext = _this$props.__relayContext,
362
375
  __rootIsQueryRenderer = _this$props.__rootIsQueryRenderer,
363
376
  props = (0, _objectWithoutPropertiesLoose2["default"])(_this$props, ["componentRef", "__relayContext", "__rootIsQueryRenderer"]);
364
- var _this$state2 = this.state,
365
- relayProp = _this$state2.relayProp,
366
- contextForChildren = _this$state2.contextForChildren;
377
+ var _this$state3 = this.state,
378
+ relayProp = _this$state3.relayProp,
379
+ contextForChildren = _this$state3.contextForChildren;
367
380
  return /*#__PURE__*/React.createElement(ReactRelayContext.Provider, {
368
381
  value: contextForChildren
369
382
  }, /*#__PURE__*/React.createElement(Component, (0, _extends2["default"])({}, props, this.state.data, {