react-relay 12.0.0 → 13.0.0-rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. package/ReactRelayContext.js +1 -1
  2. package/ReactRelayContext.js.flow +2 -3
  3. package/ReactRelayFragmentContainer.js.flow +10 -16
  4. package/ReactRelayFragmentMockRenderer.js.flow +1 -1
  5. package/ReactRelayLocalQueryRenderer.js.flow +6 -7
  6. package/ReactRelayPaginationContainer.js.flow +29 -39
  7. package/ReactRelayQueryFetcher.js.flow +9 -10
  8. package/ReactRelayQueryRenderer.js.flow +15 -15
  9. package/ReactRelayRefetchContainer.js.flow +24 -32
  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 +1 -2
  15. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +1 -2
  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 +13 -10
  22. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +13 -10
  23. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +13 -8
  24. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +13 -10
  25. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +13 -8
  26. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +13 -10
  27. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +15 -12
  28. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +15 -12
  29. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +13 -10
  30. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +13 -10
  31. package/assertFragmentMap.js.flow +2 -2
  32. package/buildReactRelayContainer.js.flow +11 -10
  33. package/getRootVariablesForFragments.js.flow +2 -4
  34. package/hooks.js +1 -1
  35. package/hooks.js.flow +3 -5
  36. package/index.js +1 -1
  37. package/index.js.flow +4 -6
  38. package/jest-react/enqueueTask.js.flow +1 -1
  39. package/jest-react/internalAct.js.flow +1 -2
  40. package/legacy.js +1 -1
  41. package/lib/ReactRelayFragmentContainer.js +4 -4
  42. package/lib/ReactRelayFragmentMockRenderer.js +2 -2
  43. package/lib/ReactRelayLocalQueryRenderer.js +7 -8
  44. package/lib/ReactRelayPaginationContainer.js +18 -22
  45. package/lib/ReactRelayQueryFetcher.js +2 -2
  46. package/lib/ReactRelayQueryRenderer.js +4 -4
  47. package/lib/ReactRelayRefetchContainer.js +12 -14
  48. package/lib/ReactRelayTestMocker.js +7 -8
  49. package/lib/RelayContext.js +3 -2
  50. package/lib/assertFragmentMap.js +2 -1
  51. package/lib/buildReactRelayContainer.js +7 -7
  52. package/lib/getRootVariablesForFragments.js +1 -2
  53. package/lib/hooks.js +5 -5
  54. package/lib/index.js +7 -7
  55. package/lib/jest-react/internalAct.js +2 -2
  56. package/lib/multi-actor/ActorChange.js +2 -2
  57. package/lib/multi-actor/useRelayActorEnvironment.js +2 -2
  58. package/lib/relay-hooks/EntryPointContainer.react.js +3 -3
  59. package/lib/relay-hooks/FragmentResource.js +241 -45
  60. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +4 -4
  61. package/lib/relay-hooks/MatchContainer.js +1 -1
  62. package/lib/relay-hooks/QueryResource.js +83 -4
  63. package/lib/relay-hooks/SuspenseResource.js +130 -0
  64. package/lib/relay-hooks/loadQuery.js +8 -9
  65. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +24 -10
  66. package/lib/relay-hooks/useBlockingPaginationFragment.js +2 -2
  67. package/lib/relay-hooks/useEntryPointLoader.js +2 -2
  68. package/lib/relay-hooks/useFetchTrackingRef.js +2 -1
  69. package/lib/relay-hooks/useFragment.js +8 -7
  70. package/lib/relay-hooks/useFragmentNode.js +4 -4
  71. package/lib/relay-hooks/useIsOperationNodeActive.js +2 -2
  72. package/lib/relay-hooks/useLazyLoadQuery.js +3 -3
  73. package/lib/relay-hooks/useLazyLoadQueryNode.js +4 -4
  74. package/lib/relay-hooks/useLoadMoreFunction.js +7 -9
  75. package/lib/relay-hooks/useMemoOperationDescriptor.js +2 -2
  76. package/lib/relay-hooks/useMemoVariables.js +2 -2
  77. package/lib/relay-hooks/useMutation.js +17 -6
  78. package/lib/relay-hooks/usePreloadedQuery.js +5 -5
  79. package/lib/relay-hooks/useQueryLoader.js +4 -4
  80. package/lib/relay-hooks/useRefetchableFragmentNode.js +10 -12
  81. package/lib/relay-hooks/useRelayEnvironment.js +2 -2
  82. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -2
  83. package/lib/relay-hooks/useSubscribeToInvalidationState.js +2 -1
  84. package/multi-actor/ActorChange.js.flow +3 -4
  85. package/multi-actor/useRelayActorEnvironment.js.flow +5 -7
  86. package/package.json +2 -2
  87. package/react-relay-hooks.js +2 -2
  88. package/react-relay-hooks.min.js +2 -2
  89. package/react-relay-legacy.js +2 -2
  90. package/react-relay-legacy.min.js +2 -2
  91. package/react-relay.js +2 -2
  92. package/react-relay.min.js +2 -2
  93. package/relay-hooks/EntryPointContainer.react.js.flow +8 -15
  94. package/relay-hooks/EntryPointTypes.flow.js.flow +18 -24
  95. package/relay-hooks/FragmentResource.js.flow +220 -34
  96. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +32 -46
  97. package/relay-hooks/MatchContainer.js.flow +3 -2
  98. package/relay-hooks/QueryResource.js.flow +119 -17
  99. package/relay-hooks/RelayEnvironmentProvider.js.flow +9 -9
  100. package/relay-hooks/SuspenseResource.js.flow +115 -0
  101. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +4 -3
  102. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +1 -1
  103. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +10 -9
  104. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +8 -7
  105. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +10 -9
  106. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +10 -9
  107. package/relay-hooks/__flowtests__/utils.js.flow +8 -12
  108. package/relay-hooks/loadEntryPoint.js.flow +6 -12
  109. package/relay-hooks/loadQuery.js.flow +22 -23
  110. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +29 -13
  111. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +6 -12
  112. package/relay-hooks/useBlockingPaginationFragment.js.flow +12 -13
  113. package/relay-hooks/useEntryPointLoader.js.flow +7 -10
  114. package/relay-hooks/useFetchTrackingRef.js.flow +2 -2
  115. package/relay-hooks/useFragment.js.flow +26 -46
  116. package/relay-hooks/useFragmentNode.js.flow +5 -7
  117. package/relay-hooks/useIsOperationNodeActive.js.flow +3 -5
  118. package/relay-hooks/useIsParentQueryActive.js.flow +3 -4
  119. package/relay-hooks/useLazyLoadQuery.js.flow +9 -10
  120. package/relay-hooks/useLazyLoadQueryNode.js.flow +11 -13
  121. package/relay-hooks/useLoadMoreFunction.js.flow +19 -27
  122. package/relay-hooks/useMemoOperationDescriptor.js.flow +5 -7
  123. package/relay-hooks/useMemoVariables.js.flow +6 -6
  124. package/relay-hooks/useMutation.js.flow +26 -26
  125. package/relay-hooks/usePaginationFragment.js.flow +37 -46
  126. package/relay-hooks/usePreloadedQuery.js.flow +13 -19
  127. package/relay-hooks/useQueryLoader.js.flow +13 -16
  128. package/relay-hooks/useRefetchableFragment.js.flow +7 -8
  129. package/relay-hooks/useRefetchableFragmentNode.js.flow +22 -30
  130. package/relay-hooks/useRelayEnvironment.js.flow +2 -4
  131. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +2 -3
  132. package/relay-hooks/useSubscribeToInvalidationState.js.flow +3 -6
  133. package/relay-hooks/useSubscription.js.flow +6 -7
@@ -14,21 +14,21 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
14
14
 
15
15
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
16
16
 
17
- var React = require('react');
17
+ var assertFragmentMap = require('./assertFragmentMap');
18
+
19
+ var _require = require('./ReactRelayContainerUtils'),
20
+ getComponentName = _require.getComponentName,
21
+ getContainerName = _require.getContainerName;
18
22
 
19
23
  var ReactRelayContext = require('./ReactRelayContext');
20
24
 
21
25
  var ReactRelayQueryRendererContext = require('./ReactRelayQueryRendererContext');
22
26
 
23
- var assertFragmentMap = require('./assertFragmentMap');
27
+ var readContext = require('./readContext');
24
28
 
25
29
  var invariant = require('invariant');
26
30
 
27
- var readContext = require('./readContext');
28
-
29
- var _require = require('./ReactRelayContainerUtils'),
30
- getComponentName = _require.getComponentName,
31
- getContainerName = _require.getContainerName;
31
+ var React = require('react');
32
32
 
33
33
  var _require2 = require('relay-runtime'),
34
34
  getFragment = _require2.getFragment;
@@ -28,8 +28,7 @@ function getRootVariablesForFragments(fragments, props) {
28
28
  var fragmentNode = fragments[key];
29
29
  var fragmentRef = props[key];
30
30
  var selector = getSelector(fragmentNode, fragmentRef);
31
- var fragmentOwnerVariables = selector != null && selector.kind === 'PluralReaderSelector' ? (_selector$selectors$ = (_selector$selectors$2 = selector.selectors[0]) === null || _selector$selectors$2 === void 0 ? void 0 : _selector$selectors$2.owner.variables) !== null && _selector$selectors$ !== void 0 ? _selector$selectors$ : {} : (_selector$owner$varia = selector === null || selector === void 0 ? void 0 : selector.owner.variables) !== null && _selector$owner$varia !== void 0 ? _selector$owner$varia : {}; // $FlowFixMe[cannot-spread-interface]
32
-
31
+ var fragmentOwnerVariables = selector != null && selector.kind === 'PluralReaderSelector' ? (_selector$selectors$ = (_selector$selectors$2 = selector.selectors[0]) === null || _selector$selectors$2 === void 0 ? void 0 : _selector$selectors$2.owner.variables) !== null && _selector$selectors$ !== void 0 ? _selector$selectors$ : {} : (_selector$owner$varia = selector === null || selector === void 0 ? void 0 : selector.owner.variables) !== null && _selector$owner$varia !== void 0 ? _selector$owner$varia : {};
33
32
  rootVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, rootVariables), fragmentOwnerVariables);
34
33
  });
35
34
  return rootVariables;
package/lib/hooks.js CHANGED
@@ -12,11 +12,12 @@
12
12
 
13
13
  var EntryPointContainer = require('./relay-hooks/EntryPointContainer.react');
14
14
 
15
- var RelayEnvironmentProvider = require('./relay-hooks/RelayEnvironmentProvider');
15
+ var loadEntryPoint = require('./relay-hooks/loadEntryPoint');
16
16
 
17
- var RelayRuntime = require('relay-runtime');
17
+ var _require = require('./relay-hooks/loadQuery'),
18
+ loadQuery = _require.loadQuery;
18
19
 
19
- var loadEntryPoint = require('./relay-hooks/loadEntryPoint');
20
+ var RelayEnvironmentProvider = require('./relay-hooks/RelayEnvironmentProvider');
20
21
 
21
22
  var useEntryPointLoader = require('./relay-hooks/useEntryPointLoader');
22
23
 
@@ -40,8 +41,7 @@ var useSubscribeToInvalidationState = require('./relay-hooks/useSubscribeToInval
40
41
 
41
42
  var useSubscription = require('./relay-hooks/useSubscription');
42
43
 
43
- var _require = require('./relay-hooks/loadQuery'),
44
- loadQuery = _require.loadQuery;
44
+ var RelayRuntime = require('relay-runtime');
45
45
 
46
46
  /**
47
47
  * The public interface for Relay Hooks.
package/lib/index.js CHANGED
@@ -10,8 +10,6 @@
10
10
  // flowlint ambiguous-object-type:error
11
11
  'use strict';
12
12
 
13
- var EntryPointContainer = require('./relay-hooks/EntryPointContainer.react');
14
-
15
13
  var ReactRelayContext = require('./ReactRelayContext');
16
14
 
17
15
  var ReactRelayFragmentContainer = require('./ReactRelayFragmentContainer');
@@ -24,12 +22,15 @@ var ReactRelayQueryRenderer = require('./ReactRelayQueryRenderer');
24
22
 
25
23
  var ReactRelayRefetchContainer = require('./ReactRelayRefetchContainer');
26
24
 
27
- var RelayEnvironmentProvider = require('./relay-hooks/RelayEnvironmentProvider');
28
-
29
- var RelayRuntime = require('relay-runtime');
25
+ var EntryPointContainer = require('./relay-hooks/EntryPointContainer.react');
30
26
 
31
27
  var loadEntryPoint = require('./relay-hooks/loadEntryPoint');
32
28
 
29
+ var _require = require('./relay-hooks/loadQuery'),
30
+ loadQuery = _require.loadQuery;
31
+
32
+ var RelayEnvironmentProvider = require('./relay-hooks/RelayEnvironmentProvider');
33
+
33
34
  var useEntryPointLoader = require('./relay-hooks/useEntryPointLoader');
34
35
 
35
36
  var useFragment = require('./relay-hooks/useFragment');
@@ -52,8 +53,7 @@ var useSubscribeToInvalidationState = require('./relay-hooks/useSubscribeToInval
52
53
 
53
54
  var useSubscription = require('./relay-hooks/useSubscription');
54
55
 
55
- var _require = require('./relay-hooks/loadQuery'),
56
- loadQuery = _require.loadQuery;
56
+ var RelayRuntime = require('relay-runtime');
57
57
 
58
58
  /**
59
59
  * The public interface to react-relay.
@@ -19,9 +19,9 @@
19
19
  // building an app with React.
20
20
  'use strict';
21
21
 
22
- var Scheduler = require('scheduler/unstable_mock');
22
+ var enqueueTask = require('./enqueueTask');
23
23
 
24
- var enqueueTask = require('./enqueueTask'); // The subset of a Promise that React APIs rely on. This resolves a value.
24
+ var Scheduler = require('scheduler/unstable_mock'); // The subset of a Promise that React APIs rely on. This resolves a value.
25
25
  // This doesn't require a return value neither from the handler nor the
26
26
  // then function.
27
27
 
@@ -10,12 +10,12 @@
10
10
  */
11
11
  'use strict';
12
12
 
13
- var React = require('react');
14
-
15
13
  var RelayEnvironmentProvider = require('../relay-hooks/RelayEnvironmentProvider');
16
14
 
17
15
  var useRelayActorEnvironment = require('./useRelayActorEnvironment');
18
16
 
17
+ var React = require('react');
18
+
19
19
  function ActorChange(props) {
20
20
  var actorEnvironment = useRelayActorEnvironment(props.actorChangePoint.__viewer);
21
21
  var getEnvironmentForActor = React.useCallback(function (actorIdentifier) {
@@ -11,13 +11,13 @@
11
11
  // flowlint ambiguous-object-type:error
12
12
  'use strict';
13
13
 
14
- var ReactRelayContext = require('react-relay/ReactRelayContext');
15
-
16
14
  var invariant = require('invariant');
17
15
 
18
16
  var _require = require('react'),
19
17
  useContext = _require.useContext;
20
18
 
19
+ var ReactRelayContext = require('react-relay/ReactRelayContext');
20
+
21
21
  function useRelayActorEnvironment(actorIdentifier) {
22
22
  var context = useContext(ReactRelayContext);
23
23
  !(context != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'useRelayActorEnvironment: Expected to have found a Relay environment provided by ' + 'a `RelayEnvironmentProvider` component. ' + 'This usually means that useRelayActorEnvironment was used in a ' + 'component that is not a descendant of a `RelayEnvironmentProvider`. ' + 'Please make sure a `RelayEnvironmentProvider` has been rendered somewhere ' + 'as a parent or ancestor of your component.') : invariant(false) : void 0;
@@ -13,16 +13,16 @@
13
13
 
14
14
  var ProfilerContext = require('./ProfilerContext');
15
15
 
16
- var React = require('react');
17
-
18
16
  var useRelayEnvironment = require('./useRelayEnvironment');
19
17
 
20
- var warning = require("fbjs/lib/warning");
18
+ var React = require('react');
21
19
 
22
20
  var _require = require('react'),
23
21
  useContext = _require.useContext,
24
22
  useEffect = _require.useEffect;
25
23
 
24
+ var warning = require("fbjs/lib/warning");
25
+
26
26
  function EntryPointContainer(_ref) {
27
27
  var entryPointReference = _ref.entryPointReference,
28
28
  props = _ref.props;
@@ -15,19 +15,32 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
15
15
 
16
16
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
17
17
 
18
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
+
18
20
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
19
21
 
20
22
  var LRUCache = require('./LRUCache');
21
23
 
24
+ var _require = require('./QueryResource'),
25
+ getQueryResourceForEnvironment = _require.getQueryResourceForEnvironment;
26
+
27
+ var SuspenseResource = require('./SuspenseResource');
28
+
22
29
  var invariant = require('invariant');
23
30
 
24
- var _require = require('relay-runtime'),
25
- getFragmentIdentifier = _require.getFragmentIdentifier,
26
- getPendingOperationsForFragment = _require.getPendingOperationsForFragment,
27
- getSelector = _require.getSelector,
28
- isPromise = _require.isPromise,
29
- recycleNodesInto = _require.recycleNodesInto,
30
- reportMissingRequiredFields = _require.reportMissingRequiredFields;
31
+ var _require2 = require('relay-runtime'),
32
+ RelayFeatureFlags = _require2.RelayFeatureFlags,
33
+ _require2$__internal = _require2.__internal,
34
+ fetchQuery = _require2$__internal.fetchQuery,
35
+ getPromiseForActiveRequest = _require2$__internal.getPromiseForActiveRequest,
36
+ createOperationDescriptor = _require2.createOperationDescriptor,
37
+ getFragmentIdentifier = _require2.getFragmentIdentifier,
38
+ getPendingOperationsForFragment = _require2.getPendingOperationsForFragment,
39
+ getSelector = _require2.getSelector,
40
+ getVariablesFromFragment = _require2.getVariablesFromFragment,
41
+ isPromise = _require2.isPromise,
42
+ recycleNodesInto = _require2.recycleNodesInto,
43
+ reportMissingRequiredFields = _require2.reportMissingRequiredFields;
31
44
 
32
45
  var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
33
46
  // TODO: Fix to not rely on LRU. If the number of active fragments exceeds this
@@ -47,6 +60,28 @@ function isMissingData(snapshot) {
47
60
  return snapshot.isMissingData;
48
61
  }
49
62
 
63
+ function hasMissingClientEdges(snapshot) {
64
+ var _snapshot$missingClie, _snapshot$missingClie2;
65
+
66
+ if (Array.isArray(snapshot)) {
67
+ return snapshot.some(function (s) {
68
+ var _s$missingClientEdges, _s$missingClientEdges2;
69
+
70
+ return ((_s$missingClientEdges = (_s$missingClientEdges2 = s.missingClientEdges) === null || _s$missingClientEdges2 === void 0 ? void 0 : _s$missingClientEdges2.length) !== null && _s$missingClientEdges !== void 0 ? _s$missingClientEdges : 0) > 0;
71
+ });
72
+ }
73
+
74
+ return ((_snapshot$missingClie = (_snapshot$missingClie2 = snapshot.missingClientEdges) === null || _snapshot$missingClie2 === void 0 ? void 0 : _snapshot$missingClie2.length) !== null && _snapshot$missingClie !== void 0 ? _snapshot$missingClie : 0) > 0;
75
+ }
76
+
77
+ function singularOrPluralForEach(snapshot, f) {
78
+ if (Array.isArray(snapshot)) {
79
+ snapshot.forEach(f);
80
+ } else {
81
+ f(snapshot);
82
+ }
83
+ }
84
+
50
85
  function getFragmentResult(cacheKey, snapshot, storeEpoch) {
51
86
  if (Array.isArray(snapshot)) {
52
87
  return {
@@ -68,11 +103,90 @@ function getFragmentResult(cacheKey, snapshot, storeEpoch) {
68
103
  storeEpoch: storeEpoch
69
104
  };
70
105
  }
106
+ /**
107
+ * The purpose of this cache is to allow information to be passed from an
108
+ * initial read which suspends through to the commit that follows a subsequent
109
+ * successful read. Specifically, the QueryResource result for the data fetch
110
+ * is passed through so that that query can be retained on commit.
111
+ */
112
+
113
+
114
+ var ClientEdgeQueryResultsCache = /*#__PURE__*/function () {
115
+ function ClientEdgeQueryResultsCache(environment) {
116
+ (0, _defineProperty2["default"])(this, "_cache", new Map());
117
+ (0, _defineProperty2["default"])(this, "_retainCounts", new Map());
118
+ this._environment = environment;
119
+ }
120
+
121
+ var _proto = ClientEdgeQueryResultsCache.prototype;
122
+
123
+ _proto.get = function get(fragmentIdentifier) {
124
+ var _this$_cache$get$, _this$_cache$get;
125
+
126
+ return (_this$_cache$get$ = (_this$_cache$get = this._cache.get(fragmentIdentifier)) === null || _this$_cache$get === void 0 ? void 0 : _this$_cache$get[0]) !== null && _this$_cache$get$ !== void 0 ? _this$_cache$get$ : undefined;
127
+ };
128
+
129
+ _proto.recordQueryResults = function recordQueryResults(fragmentIdentifier, value) {
130
+ var _this = this;
131
+
132
+ var existing = this._cache.get(fragmentIdentifier);
133
+
134
+ if (!existing) {
135
+ var suspenseResource = new SuspenseResource(function () {
136
+ return _this._retain(fragmentIdentifier);
137
+ });
138
+
139
+ this._cache.set(fragmentIdentifier, [value, suspenseResource]);
140
+
141
+ suspenseResource.temporaryRetain(this._environment);
142
+ } else {
143
+ var existingResults = existing[0],
144
+ _suspenseResource = existing[1];
145
+ value.forEach(function (queryResult) {
146
+ existingResults.push(queryResult);
147
+ });
148
+
149
+ _suspenseResource.temporaryRetain(this._environment);
150
+ }
151
+ };
152
+
153
+ _proto._retain = function _retain(id) {
154
+ var _this2 = this;
155
+
156
+ var _this$_retainCounts$g;
157
+
158
+ var retainCount = ((_this$_retainCounts$g = this._retainCounts.get(id)) !== null && _this$_retainCounts$g !== void 0 ? _this$_retainCounts$g : 0) + 1;
159
+
160
+ this._retainCounts.set(id, retainCount);
161
+
162
+ return {
163
+ dispose: function dispose() {
164
+ var _this$_retainCounts$g2;
165
+
166
+ var newRetainCount = ((_this$_retainCounts$g2 = _this2._retainCounts.get(id)) !== null && _this$_retainCounts$g2 !== void 0 ? _this$_retainCounts$g2 : 0) - 1;
167
+
168
+ if (newRetainCount > 0) {
169
+ _this2._retainCounts.set(id, newRetainCount);
170
+ } else {
171
+ _this2._retainCounts["delete"](id);
172
+
173
+ _this2._cache["delete"](id);
174
+ }
175
+ }
176
+ };
177
+ };
178
+
179
+ return ClientEdgeQueryResultsCache;
180
+ }();
71
181
 
72
182
  var FragmentResourceImpl = /*#__PURE__*/function () {
73
183
  function FragmentResourceImpl(environment) {
74
184
  this._environment = environment;
75
185
  this._cache = LRUCache.create(CACHE_CAPACITY);
186
+
187
+ if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
188
+ this._clientEdgeQueryResultsCache = new ClientEdgeQueryResultsCache(environment);
189
+ }
76
190
  }
77
191
  /**
78
192
  * This function should be called during a Component's render function,
@@ -81,9 +195,9 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
81
195
  */
82
196
 
83
197
 
84
- var _proto = FragmentResourceImpl.prototype;
198
+ var _proto2 = FragmentResourceImpl.prototype;
85
199
 
86
- _proto.read = function read(fragmentNode, fragmentRef, componentDisplayName, fragmentKey) {
200
+ _proto2.read = function read(fragmentNode, fragmentRef, componentDisplayName, fragmentKey) {
87
201
  return this.readWithIdentifier(fragmentNode, fragmentRef, getFragmentIdentifier(fragmentNode, fragmentRef), componentDisplayName, fragmentKey);
88
202
  }
89
203
  /**
@@ -93,8 +207,10 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
93
207
  */
94
208
  ;
95
209
 
96
- _proto.readWithIdentifier = function readWithIdentifier(fragmentNode, fragmentRef, fragmentIdentifier, componentDisplayName, fragmentKey) {
97
- var _fragmentNode$metadat;
210
+ _proto2.readWithIdentifier = function readWithIdentifier(fragmentNode, fragmentRef, fragmentIdentifier, componentDisplayName, fragmentKey) {
211
+ var _this3 = this;
212
+
213
+ var _fragmentNode$metadat, _clientEdgePromises;
98
214
 
99
215
  var environment = this._environment; // If fragmentRef is null or undefined, pass it directly through.
100
216
  // This is a convenience when consuming fragments via a HOC API, when the
@@ -171,18 +287,67 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
171
287
  });
172
288
 
173
289
  return fragmentResult;
174
- } // 3. If we don't have data in the store, check if a request is in
175
- // flight for the fragment's parent query, or for another operation
176
- // that may affect the parent's query data, such as a mutation
177
- // or subscription. If a promise exists, cache the promise and use it
178
- // to suspend.
290
+ } // 3. If we don't have data in the store, there's two cases where we should
291
+ // suspend to await the data: First if any client edges were traversed where
292
+ // the destination record was missing data; in that case we initiate a query
293
+ // here to fetch the missing data. Second, there may already be a request
294
+ // in flight for the fragment's parent query, or for another operation that
295
+ // may affect the parent's query data, such as a mutation or subscription.
296
+ // For any of these cases we can get a promise, which we will cache and
297
+ // suspend on.
298
+ // First, initiate a query for any client edges that were missing data:
299
+
300
+
301
+ var clientEdgeRequests = null;
302
+
303
+ if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && hasMissingClientEdges(snapshot)) {
304
+ clientEdgeRequests = [];
305
+ var queryResource = getQueryResourceForEnvironment(this._environment);
306
+ var queryResults = [];
307
+ singularOrPluralForEach(snapshot, function (snap) {
308
+ var _snap$missingClientEd;
309
+
310
+ (_snap$missingClientEd = snap.missingClientEdges) === null || _snap$missingClientEd === void 0 ? void 0 : _snap$missingClientEd.forEach(function (_ref) {
311
+ var _clientEdgeRequests;
312
+
313
+ var request = _ref.request,
314
+ clientEdgeDestinationID = _ref.clientEdgeDestinationID;
315
+
316
+ var _this3$_performClient = _this3._performClientEdgeQuery(queryResource, fragmentNode, fragmentRef, request, clientEdgeDestinationID),
317
+ queryResult = _this3$_performClient.queryResult,
318
+ requestDescriptor = _this3$_performClient.requestDescriptor;
319
+
320
+ queryResults.push(queryResult);
321
+ (_clientEdgeRequests = clientEdgeRequests) === null || _clientEdgeRequests === void 0 ? void 0 : _clientEdgeRequests.push(requestDescriptor);
322
+ });
323
+ }); // Store the query so that it can be retained when our own fragment is
324
+ // subscribed to. This merges with any existing query results:
325
+
326
+ !(this._clientEdgeQueryResultsCache != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Client edge query result cache should exist when ENABLE_CLIENT_EDGES is on.') : invariant(false) : void 0;
327
+
328
+ this._clientEdgeQueryResultsCache.recordQueryResults(fragmentIdentifier, queryResults);
329
+ }
330
+
331
+ var clientEdgePromises = null;
332
+
333
+ if (RelayFeatureFlags.ENABLE_CLIENT_EDGES && clientEdgeRequests) {
334
+ clientEdgePromises = clientEdgeRequests.map(function (request) {
335
+ return getPromiseForActiveRequest(_this3._environment, request);
336
+ }).filter(function (p) {
337
+ return p != null;
338
+ });
339
+ } // Finally look for operations in flight for our parent query:
179
340
 
180
341
 
181
342
  var fragmentOwner = fragmentSelector.kind === 'PluralReaderSelector' ? fragmentSelector.selectors[0].owner : fragmentSelector.owner;
182
343
 
183
- var networkPromiseResult = this._getAndSavePromiseForFragmentRequestInFlight(fragmentIdentifier, fragmentNode, fragmentOwner, fragmentResult);
344
+ var parentQueryPromiseResult = this._getAndSavePromiseForFragmentRequestInFlight(fragmentIdentifier, fragmentNode, fragmentOwner, fragmentResult);
345
+
346
+ var parentQueryPromiseResultPromise = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.promise; // for refinement
347
+
348
+ if (((_clientEdgePromises = clientEdgePromises) === null || _clientEdgePromises === void 0 ? void 0 : _clientEdgePromises.length) || isPromise(parentQueryPromiseResultPromise)) {
349
+ var _parentQueryPromiseRe, _clientEdgeRequests2, _clientEdgePromises2;
184
350
 
185
- if (networkPromiseResult != null && isPromise(networkPromiseResult.promise)) {
186
351
  environment.__log({
187
352
  name: 'suspense.fragment',
188
353
  data: fragmentResult.data,
@@ -190,10 +355,10 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
190
355
  isRelayHooks: true,
191
356
  isPromiseCached: false,
192
357
  isMissingData: fragmentResult.isMissingData,
193
- pendingOperations: networkPromiseResult.pendingOperations
358
+ pendingOperations: [].concat((0, _toConsumableArray2["default"])((_parentQueryPromiseRe = parentQueryPromiseResult === null || parentQueryPromiseResult === void 0 ? void 0 : parentQueryPromiseResult.pendingOperations) !== null && _parentQueryPromiseRe !== void 0 ? _parentQueryPromiseRe : []), (0, _toConsumableArray2["default"])((_clientEdgeRequests2 = clientEdgeRequests) !== null && _clientEdgeRequests2 !== void 0 ? _clientEdgeRequests2 : []))
194
359
  });
195
360
 
196
- throw networkPromiseResult.promise;
361
+ throw ((_clientEdgePromises2 = clientEdgePromises) === null || _clientEdgePromises2 === void 0 ? void 0 : _clientEdgePromises2.length) ? Promise.all([parentQueryPromiseResultPromise].concat((0, _toConsumableArray2["default"])(clientEdgePromises))) : parentQueryPromiseResultPromise;
197
362
  }
198
363
 
199
364
  this._reportMissingRequiredFieldsInSnapshot(snapshot);
@@ -201,13 +366,30 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
201
366
  return getFragmentResult(fragmentIdentifier, snapshot, storeEpoch);
202
367
  };
203
368
 
204
- _proto._reportMissingRequiredFieldsInSnapshot = function _reportMissingRequiredFieldsInSnapshot(snapshot) {
205
- var _this = this;
369
+ _proto2._performClientEdgeQuery = function _performClientEdgeQuery(queryResource, fragmentNode, fragmentRef, request, clientEdgeDestinationID) {
370
+ var originalVariables = getVariablesFromFragment(fragmentNode, fragmentRef);
371
+ var variables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, originalVariables), {}, {
372
+ id: clientEdgeDestinationID // TODO should be a reserved name
373
+
374
+ });
375
+ var operation = createOperationDescriptor(request, variables, {} // TODO cacheConfig should probably inherent from parent operation
376
+ );
377
+ var fetchObservable = fetchQuery(this._environment, operation);
378
+ var queryResult = queryResource.prepare(operation, fetchObservable // TODO should inherent render policy etc. from parent operation
379
+ );
380
+ return {
381
+ requestDescriptor: operation.request,
382
+ queryResult: queryResult
383
+ };
384
+ };
385
+
386
+ _proto2._reportMissingRequiredFieldsInSnapshot = function _reportMissingRequiredFieldsInSnapshot(snapshot) {
387
+ var _this4 = this;
206
388
 
207
389
  if (Array.isArray(snapshot)) {
208
390
  snapshot.forEach(function (s) {
209
391
  if (s.missingRequiredFields != null) {
210
- reportMissingRequiredFields(_this._environment, s.missingRequiredFields);
392
+ reportMissingRequiredFields(_this4._environment, s.missingRequiredFields);
211
393
  }
212
394
  });
213
395
  } else {
@@ -217,7 +399,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
217
399
  }
218
400
  };
219
401
 
220
- _proto.readSpec = function readSpec(fragmentNodes, fragmentRefs, componentDisplayName) {
402
+ _proto2.readSpec = function readSpec(fragmentNodes, fragmentRefs, componentDisplayName) {
221
403
  var result = {};
222
404
 
223
405
  for (var _key in fragmentNodes) {
@@ -227,8 +409,8 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
227
409
  return result;
228
410
  };
229
411
 
230
- _proto.subscribe = function subscribe(fragmentResult, callback) {
231
- var _this2 = this;
412
+ _proto2.subscribe = function subscribe(fragmentResult, callback) {
413
+ var _this5 = this;
232
414
 
233
415
  var environment = this._environment;
234
416
  var cacheKey = fragmentResult.cacheKey;
@@ -253,25 +435,25 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
253
435
  } // 3. Establish subscriptions on the snapshot(s)
254
436
 
255
437
 
256
- var dataSubscriptions = [];
438
+ var disposables = [];
257
439
 
258
440
  if (Array.isArray(renderedSnapshot)) {
259
441
  !Array.isArray(currentSnapshot) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshots to be plural. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
260
442
  currentSnapshot.forEach(function (snapshot, idx) {
261
- dataSubscriptions.push(environment.subscribe(snapshot, function (latestSnapshot) {
443
+ disposables.push(environment.subscribe(snapshot, function (latestSnapshot) {
262
444
  var storeEpoch = environment.getStore().getEpoch();
263
445
 
264
- _this2._updatePluralSnapshot(cacheKey, currentSnapshot, latestSnapshot, idx, storeEpoch);
446
+ _this5._updatePluralSnapshot(cacheKey, currentSnapshot, latestSnapshot, idx, storeEpoch);
265
447
 
266
448
  callback();
267
449
  }));
268
450
  });
269
451
  } else {
270
452
  !(currentSnapshot != null && !Array.isArray(currentSnapshot)) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected snapshot to be singular. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
271
- dataSubscriptions.push(environment.subscribe(currentSnapshot, function (latestSnapshot) {
453
+ disposables.push(environment.subscribe(currentSnapshot, function (latestSnapshot) {
272
454
  var storeEpoch = environment.getStore().getEpoch();
273
455
 
274
- _this2._cache.set(cacheKey, {
456
+ _this5._cache.set(cacheKey, {
275
457
  kind: 'done',
276
458
  result: getFragmentResult(cacheKey, latestSnapshot, storeEpoch)
277
459
  });
@@ -280,22 +462,35 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
280
462
  }));
281
463
  }
282
464
 
465
+ if (RelayFeatureFlags.ENABLE_CLIENT_EDGES) {
466
+ var _this$_clientEdgeQuer, _this$_clientEdgeQuer2;
467
+
468
+ var clientEdgeQueryResults = (_this$_clientEdgeQuer = (_this$_clientEdgeQuer2 = this._clientEdgeQueryResultsCache) === null || _this$_clientEdgeQuer2 === void 0 ? void 0 : _this$_clientEdgeQuer2.get(cacheKey)) !== null && _this$_clientEdgeQuer !== void 0 ? _this$_clientEdgeQuer : undefined;
469
+
470
+ if (clientEdgeQueryResults === null || clientEdgeQueryResults === void 0 ? void 0 : clientEdgeQueryResults.length) {
471
+ var queryResource = getQueryResourceForEnvironment(this._environment);
472
+ clientEdgeQueryResults.forEach(function (queryResult) {
473
+ disposables.push(queryResource.retain(queryResult));
474
+ });
475
+ }
476
+ }
477
+
283
478
  return {
284
479
  dispose: function dispose() {
285
- dataSubscriptions.map(function (s) {
480
+ disposables.forEach(function (s) {
286
481
  return s.dispose();
287
482
  });
288
483
 
289
- _this2._cache["delete"](cacheKey);
484
+ _this5._cache["delete"](cacheKey);
290
485
  }
291
486
  };
292
487
  };
293
488
 
294
- _proto.subscribeSpec = function subscribeSpec(fragmentResults, callback) {
295
- var _this3 = this;
489
+ _proto2.subscribeSpec = function subscribeSpec(fragmentResults, callback) {
490
+ var _this6 = this;
296
491
 
297
492
  var disposables = Object.keys(fragmentResults).map(function (key) {
298
- return _this3.subscribe(fragmentResults[key], callback);
493
+ return _this6.subscribe(fragmentResults[key], callback);
299
494
  });
300
495
  return {
301
496
  dispose: function dispose() {
@@ -306,7 +501,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
306
501
  };
307
502
  };
308
503
 
309
- _proto.checkMissedUpdates = function checkMissedUpdates(fragmentResult) {
504
+ _proto2.checkMissedUpdates = function checkMissedUpdates(fragmentResult) {
310
505
  var environment = this._environment;
311
506
  var renderedSnapshot = fragmentResult.snapshot;
312
507
 
@@ -361,6 +556,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
361
556
  var updatedCurrentSnapshot = {
362
557
  data: updatedData,
363
558
  isMissingData: currentSnapshot.isMissingData,
559
+ missingClientEdges: currentSnapshot.missingClientEdges,
364
560
  seenRecords: currentSnapshot.seenRecords,
365
561
  selector: currentSnapshot.selector,
366
562
  missingRequiredFields: currentSnapshot.missingRequiredFields
@@ -376,16 +572,16 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
376
572
  return [updatedData !== renderData, updatedCurrentSnapshot];
377
573
  };
378
574
 
379
- _proto.checkMissedUpdatesSpec = function checkMissedUpdatesSpec(fragmentResults) {
380
- var _this4 = this;
575
+ _proto2.checkMissedUpdatesSpec = function checkMissedUpdatesSpec(fragmentResults) {
576
+ var _this7 = this;
381
577
 
382
578
  return Object.keys(fragmentResults).some(function (key) {
383
- return _this4.checkMissedUpdates(fragmentResults[key])[0];
579
+ return _this7.checkMissedUpdates(fragmentResults[key])[0];
384
580
  });
385
581
  };
386
582
 
387
- _proto._getAndSavePromiseForFragmentRequestInFlight = function _getAndSavePromiseForFragmentRequestInFlight(cacheKey, fragmentNode, fragmentOwner, fragmentResult) {
388
- var _this5 = this;
583
+ _proto2._getAndSavePromiseForFragmentRequestInFlight = function _getAndSavePromiseForFragmentRequestInFlight(cacheKey, fragmentNode, fragmentOwner, fragmentResult) {
584
+ var _this8 = this;
389
585
 
390
586
  var pendingOperationsResult = getPendingOperationsForFragment(this._environment, fragmentNode, fragmentOwner);
391
587
 
@@ -399,9 +595,9 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
399
595
  var networkPromise = pendingOperationsResult.promise;
400
596
  var pendingOperations = pendingOperationsResult.pendingOperations;
401
597
  var promise = networkPromise.then(function () {
402
- _this5._cache["delete"](cacheKey);
598
+ _this8._cache["delete"](cacheKey);
403
599
  })["catch"](function (error) {
404
- _this5._cache["delete"](cacheKey);
600
+ _this8._cache["delete"](cacheKey);
405
601
  }); // $FlowExpectedError[prop-missing] Expando to annotate Promises.
406
602
 
407
603
  promise.displayName = networkPromise.displayName;
@@ -419,7 +615,7 @@ var FragmentResourceImpl = /*#__PURE__*/function () {
419
615
  };
420
616
  };
421
617
 
422
- _proto._updatePluralSnapshot = function _updatePluralSnapshot(cacheKey, baseSnapshots, latestSnapshot, idx, storeEpoch) {
618
+ _proto2._updatePluralSnapshot = function _updatePluralSnapshot(cacheKey, baseSnapshots, latestSnapshot, idx, storeEpoch) {
423
619
  var _currentFragmentResul;
424
620
 
425
621
  var currentFragmentResult = this._cache.get(cacheKey);
@@ -11,14 +11,14 @@
11
11
  // flowlint ambiguous-object-type:error
12
12
  'use strict';
13
13
 
14
- var ProfilerContext = require('./ProfilerContext');
15
-
16
- var React = require('react');
17
-
18
14
  var preloadQuery_DEPRECATED = require('./preloadQuery_DEPRECATED');
19
15
 
16
+ var ProfilerContext = require('./ProfilerContext');
17
+
20
18
  var useRelayEnvironment = require('./useRelayEnvironment');
21
19
 
20
+ var React = require('react');
21
+
22
22
  var _require = require('react'),
23
23
  useContext = _require.useContext,
24
24
  useEffect = _require.useEffect,
@@ -98,7 +98,7 @@ function MatchContainer(_ref2) {
98
98
 
99
99
  if (match != null && typeof match !== 'object') {
100
100
  throw new Error('MatchContainer: Expected `match` value to be an object or null/undefined.');
101
- } // NOTE: the MatchPointer type has a $fragmentRefs field to ensure that only
101
+ } // NOTE: the MatchPointer type has a $fragmentSpreads field to ensure that only
102
102
  // an object that contains a FragmentSpread can be passed. If the fragment
103
103
  // spread matches, then the metadata fields below (__id, __fragments, etc.)
104
104
  // will be present. But they can be missing if all the fragment spreads use