react-relay 11.0.2 → 13.0.0-rc.2

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 (177) hide show
  1. package/README.md +47 -0
  2. package/ReactRelayContainerUtils.js.flow +1 -1
  3. package/ReactRelayContext.js +1 -1
  4. package/ReactRelayContext.js.flow +3 -4
  5. package/ReactRelayFragmentContainer.js.flow +25 -25
  6. package/ReactRelayFragmentMockRenderer.js.flow +2 -2
  7. package/ReactRelayLocalQueryRenderer.js.flow +7 -8
  8. package/ReactRelayPaginationContainer.js.flow +112 -59
  9. package/ReactRelayQueryFetcher.js.flow +10 -11
  10. package/ReactRelayQueryRenderer.js.flow +116 -82
  11. package/ReactRelayQueryRendererContext.js.flow +1 -1
  12. package/ReactRelayRefetchContainer.js.flow +42 -39
  13. package/ReactRelayTestMocker.js.flow +17 -15
  14. package/ReactRelayTypes.js.flow +11 -11
  15. package/RelayContext.js.flow +4 -4
  16. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -3
  17. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +12 -8
  18. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +11 -7
  19. package/__flowtests__/RelayModern-flowtest.js.flow +79 -47
  20. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +6 -5
  21. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +6 -5
  22. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +5 -4
  23. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +5 -4
  24. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +72 -0
  25. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +72 -0
  26. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +227 -0
  27. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +164 -0
  28. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +227 -0
  29. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +164 -0
  30. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +66 -0
  31. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +66 -0
  32. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +59 -0
  33. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +61 -0
  34. package/assertFragmentMap.js.flow +3 -3
  35. package/buildReactRelayContainer.js.flow +12 -11
  36. package/getRootVariablesForFragments.js.flow +3 -5
  37. package/hooks.js +1 -1
  38. package/hooks.js.flow +6 -7
  39. package/index.js +1 -1
  40. package/index.js.flow +7 -8
  41. package/isRelayEnvironment.js.flow +1 -1
  42. package/jest-react/enqueueTask.js.flow +56 -0
  43. package/jest-react/index.js.flow +12 -0
  44. package/jest-react/internalAct.js.flow +138 -0
  45. package/legacy.js +1 -1
  46. package/legacy.js.flow +1 -1
  47. package/lib/ReactRelayContainerUtils.js +1 -1
  48. package/lib/ReactRelayContext.js +1 -1
  49. package/lib/ReactRelayFragmentContainer.js +22 -16
  50. package/lib/ReactRelayFragmentMockRenderer.js +3 -3
  51. package/lib/ReactRelayLocalQueryRenderer.js +8 -9
  52. package/lib/ReactRelayPaginationContainer.js +97 -39
  53. package/lib/ReactRelayQueryFetcher.js +3 -3
  54. package/lib/ReactRelayQueryRenderer.js +87 -54
  55. package/lib/ReactRelayQueryRendererContext.js +1 -1
  56. package/lib/ReactRelayRefetchContainer.js +39 -26
  57. package/lib/ReactRelayTestMocker.js +8 -9
  58. package/lib/ReactRelayTypes.js +1 -1
  59. package/lib/RelayContext.js +4 -3
  60. package/lib/assertFragmentMap.js +3 -2
  61. package/lib/buildReactRelayContainer.js +8 -8
  62. package/lib/getRootVariablesForFragments.js +2 -3
  63. package/lib/hooks.js +6 -6
  64. package/lib/index.js +8 -8
  65. package/lib/isRelayEnvironment.js +1 -1
  66. package/lib/jest-react/enqueueTask.js +53 -0
  67. package/lib/jest-react/index.js +13 -0
  68. package/lib/jest-react/internalAct.js +115 -0
  69. package/lib/legacy.js +1 -1
  70. package/lib/multi-actor/ActorChange.js +30 -0
  71. package/lib/multi-actor/index.js +11 -0
  72. package/lib/multi-actor/useRelayActorEnvironment.js +29 -0
  73. package/lib/readContext.js +1 -1
  74. package/lib/relay-hooks/EntryPointContainer.react.js +4 -4
  75. package/lib/relay-hooks/EntryPointTypes.flow.js +1 -1
  76. package/lib/relay-hooks/FragmentResource.js +342 -89
  77. package/lib/relay-hooks/InternalLogger.js +1 -1
  78. package/lib/relay-hooks/LRUCache.js +1 -1
  79. package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +5 -5
  80. package/lib/relay-hooks/MatchContainer.js +2 -2
  81. package/lib/relay-hooks/ProfilerContext.js +1 -1
  82. package/lib/relay-hooks/QueryResource.js +172 -29
  83. package/lib/relay-hooks/RelayEnvironmentProvider.js +6 -4
  84. package/lib/relay-hooks/SuspenseResource.js +130 -0
  85. package/lib/relay-hooks/loadEntryPoint.js +1 -1
  86. package/lib/relay-hooks/loadQuery.js +42 -20
  87. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +25 -16
  88. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +1 -1
  89. package/lib/relay-hooks/useBlockingPaginationFragment.js +5 -6
  90. package/lib/relay-hooks/useEntryPointLoader.js +3 -3
  91. package/lib/relay-hooks/useFetchTrackingRef.js +3 -2
  92. package/lib/relay-hooks/useFragment.js +7 -7
  93. package/lib/relay-hooks/useFragmentNode.js +5 -5
  94. package/lib/relay-hooks/useIsMountedRef.js +1 -1
  95. package/lib/relay-hooks/useIsOperationNodeActive.js +3 -3
  96. package/lib/relay-hooks/useIsParentQueryActive.js +1 -1
  97. package/lib/relay-hooks/useLazyLoadQuery.js +4 -4
  98. package/lib/relay-hooks/useLazyLoadQueryNode.js +11 -5
  99. package/lib/relay-hooks/useLoadMoreFunction.js +9 -13
  100. package/lib/relay-hooks/useMemoOperationDescriptor.js +3 -3
  101. package/lib/relay-hooks/useMemoVariables.js +3 -3
  102. package/lib/relay-hooks/useMutation.js +18 -7
  103. package/lib/relay-hooks/usePaginationFragment.js +3 -4
  104. package/lib/relay-hooks/usePreloadedQuery.js +6 -6
  105. package/lib/relay-hooks/useQueryLoader.js +31 -11
  106. package/lib/relay-hooks/useRefetchableFragment.js +1 -1
  107. package/lib/relay-hooks/useRefetchableFragmentNode.js +14 -18
  108. package/lib/relay-hooks/useRelayEnvironment.js +3 -3
  109. package/lib/relay-hooks/useStaticFragmentNodeWarning.js +3 -3
  110. package/lib/relay-hooks/useSubscribeToInvalidationState.js +3 -2
  111. package/lib/relay-hooks/useSubscription.js +11 -8
  112. package/multi-actor/ActorChange.js.flow +58 -0
  113. package/multi-actor/index.js.flow +14 -0
  114. package/multi-actor/useRelayActorEnvironment.js.flow +49 -0
  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 -1
  123. package/relay-hooks/EntryPointContainer.react.js.flow +9 -16
  124. package/relay-hooks/EntryPointTypes.flow.js.flow +25 -26
  125. package/relay-hooks/FragmentResource.js.flow +359 -93
  126. package/relay-hooks/InternalLogger.js.flow +1 -1
  127. package/relay-hooks/LRUCache.js.flow +1 -1
  128. package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +33 -47
  129. package/relay-hooks/MatchContainer.js.flow +4 -3
  130. package/relay-hooks/ProfilerContext.js.flow +1 -1
  131. package/relay-hooks/QueryResource.js.flow +217 -26
  132. package/relay-hooks/RelayEnvironmentProvider.js.flow +15 -5
  133. package/relay-hooks/SuspenseResource.js.flow +115 -0
  134. package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +5 -4
  135. package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +2 -2
  136. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_user.graphql.js.flow +59 -0
  137. package/relay-hooks/__flowtests__/__generated__/useFragmentFlowtest_users.graphql.js.flow +61 -0
  138. package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +11 -10
  139. package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +55 -32
  140. package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +11 -10
  141. package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +11 -10
  142. package/relay-hooks/__flowtests__/utils.js.flow +21 -32
  143. package/relay-hooks/loadEntryPoint.js.flow +7 -13
  144. package/relay-hooks/loadQuery.js.flow +50 -32
  145. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +31 -22
  146. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +7 -13
  147. package/relay-hooks/useBlockingPaginationFragment.js.flow +14 -12
  148. package/relay-hooks/useEntryPointLoader.js.flow +8 -11
  149. package/relay-hooks/useFetchTrackingRef.js.flow +3 -3
  150. package/relay-hooks/useFragment.js.flow +31 -62
  151. package/relay-hooks/useFragmentNode.js.flow +6 -8
  152. package/relay-hooks/useIsMountedRef.js.flow +1 -1
  153. package/relay-hooks/useIsOperationNodeActive.js.flow +4 -6
  154. package/relay-hooks/useIsParentQueryActive.js.flow +4 -5
  155. package/relay-hooks/useLazyLoadQuery.js.flow +14 -16
  156. package/relay-hooks/useLazyLoadQueryNode.js.flow +20 -14
  157. package/relay-hooks/useLoadMoreFunction.js.flow +21 -30
  158. package/relay-hooks/useMemoOperationDescriptor.js.flow +6 -8
  159. package/relay-hooks/useMemoVariables.js.flow +7 -7
  160. package/relay-hooks/useMutation.js.flow +27 -27
  161. package/relay-hooks/usePaginationFragment.js.flow +39 -45
  162. package/relay-hooks/usePreloadedQuery.js.flow +14 -20
  163. package/relay-hooks/useQueryLoader.js.flow +42 -23
  164. package/relay-hooks/useRefetchableFragment.js.flow +8 -9
  165. package/relay-hooks/useRefetchableFragmentNode.js.flow +25 -33
  166. package/relay-hooks/useRelayEnvironment.js.flow +3 -5
  167. package/relay-hooks/useStaticFragmentNodeWarning.js.flow +3 -4
  168. package/relay-hooks/useSubscribeToInvalidationState.js.flow +4 -7
  169. package/relay-hooks/useSubscription.js.flow +21 -11
  170. package/lib/relay-hooks/getPaginationMetadata.js +0 -41
  171. package/lib/relay-hooks/getPaginationVariables.js +0 -67
  172. package/lib/relay-hooks/getRefetchMetadata.js +0 -36
  173. package/lib/relay-hooks/getValueAtPath.js +0 -51
  174. package/relay-hooks/getPaginationMetadata.js.flow +0 -74
  175. package/relay-hooks/getPaginationVariables.js.flow +0 -110
  176. package/relay-hooks/getRefetchMetadata.js.flow +0 -80
  177. package/relay-hooks/getValueAtPath.js.flow +0 -46
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -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,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -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
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -19,16 +19,24 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
19
19
 
20
20
  var LRUCache = require('./LRUCache');
21
21
 
22
+ var SuspenseResource = require('./SuspenseResource');
23
+
22
24
  var invariant = require('invariant');
23
25
 
24
26
  var _require = require('relay-runtime'),
27
+ RelayFeatureFlags = _require.RelayFeatureFlags,
25
28
  isPromise = _require.isPromise;
26
29
 
30
+ var warning = require("fbjs/lib/warning");
31
+
27
32
  var CACHE_CAPACITY = 1000;
28
33
  var DEFAULT_FETCH_POLICY = 'store-or-network';
29
- var DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
30
34
  var WEAKMAP_SUPPORTED = typeof WeakMap === 'function';
31
35
 
36
+ function operationIsLiveQuery(operation) {
37
+ return operation.request.node.params.metadata.live !== undefined;
38
+ }
39
+
32
40
  function getQueryCacheIdentifier(environment, operation, maybeFetchPolicy, maybeRenderPolicy, cacheBreaker) {
33
41
  var fetchPolicy = maybeFetchPolicy !== null && maybeFetchPolicy !== void 0 ? maybeFetchPolicy : DEFAULT_FETCH_POLICY;
34
42
  var renderPolicy = maybeRenderPolicy !== null && maybeRenderPolicy !== void 0 ? maybeRenderPolicy : environment.UNSTABLE_getDefaultRenderPolicy();
@@ -57,11 +65,83 @@ function getQueryResult(operation, cacheIdentifier) {
57
65
 
58
66
  var nextID = 200000;
59
67
 
60
- function createCacheEntry(cacheIdentifier, operation, value, networkSubscription, onDispose) {
68
+ function createCacheEntry(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
69
+ // There should be no behavior difference between createCacheEntry_new and
70
+ // createCacheEntry_old, and it doesn't directly relate to Client Edges.
71
+ // It was just a refactoring that was needed for Client Edges but that
72
+ // is behind the feature flag just in case there is any accidental breakage.
73
+ if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
74
+ return createCacheEntry_new(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose);
75
+ } else {
76
+ return createCacheEntry_old(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose);
77
+ }
78
+ }
79
+
80
+ function createCacheEntry_new(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
81
+ var isLiveQuery = operationIsLiveQuery(operation);
82
+ var currentValue = value;
83
+ var currentNetworkSubscription = networkSubscription;
84
+ var suspenseResource = new SuspenseResource(function (environment) {
85
+ var retention = environment.retain(operation);
86
+ return {
87
+ dispose: function dispose() {
88
+ // Normally if this entry never commits, the request would've ended by the
89
+ // time this timeout expires and the temporary retain is released. However,
90
+ // we need to do this for live queries which remain open indefinitely.
91
+ if (isLiveQuery && currentNetworkSubscription != null) {
92
+ currentNetworkSubscription.unsubscribe();
93
+ }
94
+
95
+ retention.dispose();
96
+ onDispose(cacheEntry);
97
+ }
98
+ };
99
+ });
100
+ var cacheEntry = {
101
+ cacheIdentifier: cacheIdentifier,
102
+ id: nextID++,
103
+ processedPayloadsCount: 0,
104
+ operationAvailability: operationAvailability,
105
+ getValue: function getValue() {
106
+ return currentValue;
107
+ },
108
+ setValue: function setValue(val) {
109
+ currentValue = val;
110
+ },
111
+ getRetainCount: function getRetainCount() {
112
+ return suspenseResource.getRetainCount();
113
+ },
114
+ getNetworkSubscription: function getNetworkSubscription() {
115
+ return currentNetworkSubscription;
116
+ },
117
+ setNetworkSubscription: function setNetworkSubscription(subscription) {
118
+ if (isLiveQuery && currentNetworkSubscription != null) {
119
+ currentNetworkSubscription.unsubscribe();
120
+ }
121
+
122
+ currentNetworkSubscription = subscription;
123
+ },
124
+ temporaryRetain: function temporaryRetain(environment) {
125
+ return suspenseResource.temporaryRetain(environment);
126
+ },
127
+ permanentRetain: function permanentRetain(environment) {
128
+ return suspenseResource.permanentRetain(environment);
129
+ },
130
+ releaseTemporaryRetain: function releaseTemporaryRetain() {
131
+ suspenseResource.releaseTemporaryRetain();
132
+ }
133
+ };
134
+ return cacheEntry;
135
+ }
136
+
137
+ var DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
138
+
139
+ function createCacheEntry_old(cacheIdentifier, operation, operationAvailability, value, networkSubscription, onDispose) {
140
+ var isLiveQuery = operationIsLiveQuery(operation);
61
141
  var currentValue = value;
62
142
  var retainCount = 0;
63
143
  var retainDisposable = null;
64
- var releaseTemporaryRetain = null;
144
+ var _releaseTemporaryRetain = null;
65
145
  var currentNetworkSubscription = networkSubscription;
66
146
 
67
147
  var retain = function retain(environment) {
@@ -89,6 +169,8 @@ function createCacheEntry(cacheIdentifier, operation, value, networkSubscription
89
169
  var cacheEntry = {
90
170
  cacheIdentifier: cacheIdentifier,
91
171
  id: nextID++,
172
+ processedPayloadsCount: 0,
173
+ operationAvailability: operationAvailability,
92
174
  getValue: function getValue() {
93
175
  return currentValue;
94
176
  },
@@ -102,7 +184,7 @@ function createCacheEntry(cacheIdentifier, operation, value, networkSubscription
102
184
  return currentNetworkSubscription;
103
185
  },
104
186
  setNetworkSubscription: function setNetworkSubscription(subscription) {
105
- if (currentNetworkSubscription != null) {
187
+ if (isLiveQuery && currentNetworkSubscription != null) {
106
188
  currentNetworkSubscription.unsubscribe();
107
189
  }
108
190
 
@@ -129,12 +211,12 @@ function createCacheEntry(cacheIdentifier, operation, value, networkSubscription
129
211
  var localReleaseTemporaryRetain = function localReleaseTemporaryRetain() {
130
212
  clearTimeout(releaseQueryTimeout);
131
213
  releaseQueryTimeout = null;
132
- releaseTemporaryRetain = null;
214
+ _releaseTemporaryRetain = null;
133
215
  disposable.dispose(); // Normally if this entry never commits, the request would've ended by the
134
216
  // time this timeout expires and the temporary retain is released. However,
135
217
  // we need to do this for live queries which remain open indefinitely.
136
218
 
137
- if (retainCount <= 0 && currentNetworkSubscription != null) {
219
+ if (isLiveQuery && retainCount <= 0 && currentNetworkSubscription != null) {
138
220
  currentNetworkSubscription.unsubscribe();
139
221
  }
140
222
  };
@@ -147,34 +229,42 @@ function createCacheEntry(cacheIdentifier, operation, value, networkSubscription
147
229
  // phase, as well as multiple times by other query components that are
148
230
  // rendering the same query/variables.
149
231
 
150
- if (releaseTemporaryRetain != null) {
151
- releaseTemporaryRetain();
232
+ if (_releaseTemporaryRetain != null) {
233
+ _releaseTemporaryRetain();
152
234
  }
153
235
 
154
- releaseTemporaryRetain = localReleaseTemporaryRetain;
236
+ _releaseTemporaryRetain = localReleaseTemporaryRetain;
155
237
  return {
156
238
  dispose: function dispose() {
157
- releaseTemporaryRetain && releaseTemporaryRetain();
239
+ _releaseTemporaryRetain && _releaseTemporaryRetain();
158
240
  }
159
241
  };
160
242
  },
161
243
  permanentRetain: function permanentRetain(environment) {
162
244
  var disposable = retain(environment);
163
245
 
164
- if (releaseTemporaryRetain != null) {
165
- releaseTemporaryRetain();
166
- releaseTemporaryRetain = null;
246
+ if (_releaseTemporaryRetain != null) {
247
+ _releaseTemporaryRetain();
248
+
249
+ _releaseTemporaryRetain = null;
167
250
  }
168
251
 
169
252
  return {
170
253
  dispose: function dispose() {
171
254
  disposable.dispose();
172
255
 
173
- if (retainCount <= 0 && currentNetworkSubscription != null) {
256
+ if (isLiveQuery && retainCount <= 0 && currentNetworkSubscription != null) {
174
257
  currentNetworkSubscription.unsubscribe();
175
258
  }
176
259
  }
177
260
  };
261
+ },
262
+ releaseTemporaryRetain: function releaseTemporaryRetain() {
263
+ if (_releaseTemporaryRetain != null) {
264
+ _releaseTemporaryRetain();
265
+
266
+ _releaseTemporaryRetain = null;
267
+ }
178
268
  }
179
269
  };
180
270
  return cacheEntry;
@@ -185,8 +275,14 @@ var QueryResourceImpl = /*#__PURE__*/function () {
185
275
  var _this = this;
186
276
 
187
277
  (0, _defineProperty2["default"])(this, "_clearCacheEntry", function (cacheEntry) {
188
- if (cacheEntry.getRetainCount() <= 0) {
278
+ // The new code does this retainCount <= 0 check within SuspenseResource
279
+ // before calling _clearCacheEntry, whereas with the old code we do it here.
280
+ if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
189
281
  _this._cache["delete"](cacheEntry.cacheIdentifier);
282
+ } else {
283
+ if (cacheEntry.getRetainCount() <= 0) {
284
+ _this._cache["delete"](cacheEntry.cacheIdentifier);
285
+ }
190
286
  }
191
287
  });
192
288
  this._environment = environment;
@@ -215,6 +311,7 @@ var QueryResourceImpl = /*#__PURE__*/function () {
215
311
  var cacheEntry = this._cache.get(cacheIdentifier);
216
312
 
217
313
  var temporaryRetainDisposable = null;
314
+ var entryWasCached = cacheEntry != null;
218
315
 
219
316
  if (cacheEntry == null) {
220
317
  // 2. If a cached value isn't available, try fetching the operation.
@@ -245,7 +342,20 @@ var QueryResourceImpl = /*#__PURE__*/function () {
245
342
  temporaryRetainDisposable = cacheEntry.temporaryRetain(environment);
246
343
  var cachedValue = cacheEntry.getValue();
247
344
 
248
- if (isPromise(cachedValue) || cachedValue instanceof Error) {
345
+ if (isPromise(cachedValue)) {
346
+ environment.__log({
347
+ name: 'suspense.query',
348
+ fetchPolicy: fetchPolicy,
349
+ isPromiseCached: entryWasCached,
350
+ operation: operation,
351
+ queryAvailability: cacheEntry.operationAvailability,
352
+ renderPolicy: renderPolicy
353
+ });
354
+
355
+ throw cachedValue;
356
+ }
357
+
358
+ if (cachedValue instanceof Error) {
249
359
  throw cachedValue;
250
360
  }
251
361
 
@@ -263,7 +373,7 @@ var QueryResourceImpl = /*#__PURE__*/function () {
263
373
  var cacheIdentifier = queryResult.cacheIdentifier,
264
374
  operation = queryResult.operation;
265
375
 
266
- var cacheEntry = this._getOrCreateCacheEntry(cacheIdentifier, operation, queryResult, null);
376
+ var cacheEntry = this._getOrCreateCacheEntry(cacheIdentifier, operation, null, queryResult, null);
267
377
 
268
378
  var disposable = cacheEntry.permanentRetain(environment);
269
379
 
@@ -280,17 +390,25 @@ var QueryResourceImpl = /*#__PURE__*/function () {
280
390
  };
281
391
  };
282
392
 
393
+ _proto.releaseTemporaryRetain = function releaseTemporaryRetain(queryResult) {
394
+ var cacheEntry = this._cache.get(queryResult.cacheIdentifier);
395
+
396
+ if (cacheEntry != null) {
397
+ cacheEntry.releaseTemporaryRetain();
398
+ }
399
+ };
400
+
283
401
  _proto.TESTS_ONLY__getCacheEntry = function TESTS_ONLY__getCacheEntry(operation, maybeFetchPolicy, maybeRenderPolicy, cacheBreaker) {
284
402
  var environment = this._environment;
285
403
  var cacheIdentifier = getQueryCacheIdentifier(environment, operation, maybeFetchPolicy, maybeRenderPolicy, cacheBreaker);
286
404
  return this._cache.get(cacheIdentifier);
287
405
  };
288
406
 
289
- _proto._getOrCreateCacheEntry = function _getOrCreateCacheEntry(cacheIdentifier, operation, value, networkSubscription) {
407
+ _proto._getOrCreateCacheEntry = function _getOrCreateCacheEntry(cacheIdentifier, operation, operationAvailability, value, networkSubscription) {
290
408
  var cacheEntry = this._cache.get(cacheIdentifier);
291
409
 
292
410
  if (cacheEntry == null) {
293
- cacheEntry = createCacheEntry(cacheIdentifier, operation, value, networkSubscription, this._clearCacheEntry);
411
+ cacheEntry = createCacheEntry(cacheIdentifier, operation, operationAvailability, value, networkSubscription, this._clearCacheEntry);
294
412
 
295
413
  this._cache.set(cacheIdentifier, cacheEntry);
296
414
  }
@@ -353,7 +471,7 @@ var QueryResourceImpl = /*#__PURE__*/function () {
353
471
  if (shouldAllowRender) {
354
472
  var queryResult = getQueryResult(operation, cacheIdentifier);
355
473
 
356
- var _cacheEntry = createCacheEntry(cacheIdentifier, operation, queryResult, null, this._clearCacheEntry);
474
+ var _cacheEntry = createCacheEntry(cacheIdentifier, operation, queryAvailability, queryResult, null, this._clearCacheEntry);
357
475
 
358
476
  this._cache.set(cacheIdentifier, _cacheEntry);
359
477
  }
@@ -373,22 +491,47 @@ var QueryResourceImpl = /*#__PURE__*/function () {
373
491
  }
374
492
 
375
493
  var observerStart = observer === null || observer === void 0 ? void 0 : observer.start;
376
- observerStart && observerStart(subscription);
494
+
495
+ if (observerStart) {
496
+ var subscriptionWithConditionalCancelation = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, subscription), {}, {
497
+ unsubscribe: function unsubscribe() {
498
+ // Only live queries should have their network requests canceled.
499
+ if (operationIsLiveQuery(operation)) {
500
+ subscription.unsubscribe();
501
+ }
502
+ }
503
+ });
504
+ observerStart(subscriptionWithConditionalCancelation);
505
+ }
377
506
  },
378
507
  next: function next() {
379
- var snapshot = environment.lookup(operation.fragment);
380
-
381
- var cacheEntry = _this2._getOrCreateCacheEntry(cacheIdentifier, operation, _queryResult, networkSubscription);
508
+ var cacheEntry = _this2._getOrCreateCacheEntry(cacheIdentifier, operation, queryAvailability, _queryResult, networkSubscription);
382
509
 
510
+ cacheEntry.processedPayloadsCount += 1;
383
511
  cacheEntry.setValue(_queryResult);
384
512
  resolveNetworkPromise();
385
513
  var observerNext = observer === null || observer === void 0 ? void 0 : observer.next;
386
- observerNext && observerNext(snapshot);
514
+
515
+ if (observerNext != null) {
516
+ var snapshot = environment.lookup(operation.fragment);
517
+ observerNext(snapshot);
518
+ }
387
519
  },
388
520
  error: function error(_error) {
389
- var cacheEntry = _this2._getOrCreateCacheEntry(cacheIdentifier, operation, _error, networkSubscription);
521
+ var cacheEntry = _this2._getOrCreateCacheEntry(cacheIdentifier, operation, queryAvailability, _error, networkSubscription); // If, this is the first thing we receive for the query,
522
+ // before any other payload handled is error, we will cache and
523
+ // re-throw that error later.
524
+ // We will ignore errors for any incremental payloads we receive.
525
+
526
+
527
+ if (cacheEntry.processedPayloadsCount === 0) {
528
+ cacheEntry.setValue(_error);
529
+ } else {
530
+ // TODO:T92030819 Remove this warning and actually throw the network error
531
+ // To complete this task we need to have a way of precisely tracking suspendable points
532
+ process.env.NODE_ENV !== "production" ? warning(false, 'QueryResource: An incremental payload for query `%` returned an error: `%`:`%`.', operation.fragment.node.name, _error.message, _error.stack) : void 0;
533
+ }
390
534
 
391
- cacheEntry.setValue(_error);
392
535
  resolveNetworkPromise();
393
536
  networkSubscription = null;
394
537
  cacheEntry.setNetworkSubscription(null);
@@ -419,7 +562,7 @@ var QueryResourceImpl = /*#__PURE__*/function () {
419
562
  }); // $FlowExpectedError[prop-missing] Expando to annotate Promises.
420
563
 
421
564
  networkPromise.displayName = 'Relay(' + operation.fragment.node.name + ')';
422
- _cacheEntry2 = createCacheEntry(cacheIdentifier, operation, networkPromise, networkSubscription, this._clearCacheEntry);
565
+ _cacheEntry2 = createCacheEntry(cacheIdentifier, operation, queryAvailability, networkPromise, networkSubscription, this._clearCacheEntry);
423
566
 
424
567
  this._cache.set(cacheIdentifier, _cacheEntry2);
425
568
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
@@ -19,12 +19,14 @@ var useMemo = React.useMemo;
19
19
 
20
20
  function RelayEnvironmentProvider(props) {
21
21
  var children = props.children,
22
- environment = props.environment;
22
+ environment = props.environment,
23
+ getEnvironmentForActor = props.getEnvironmentForActor;
23
24
  var context = useMemo(function () {
24
25
  return {
25
- environment: environment
26
+ environment: environment,
27
+ getEnvironmentForActor: getEnvironmentForActor
26
28
  };
27
- }, [environment]);
29
+ }, [environment, getEnvironmentForActor]);
28
30
  return /*#__PURE__*/React.createElement(ReactRelayContext.Provider, {
29
31
  value: context
30
32
  }, children);
@@ -0,0 +1,130 @@
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
+ *
8
+ * @emails oncall+relay
9
+ * @format
10
+ */
11
+ // flowlint ambiguous-object-type:error
12
+ 'use strict';
13
+
14
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
15
+
16
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
17
+
18
+ var invariant = require('invariant');
19
+
20
+ var TEMPORARY_RETAIN_DURATION_MS = 5 * 60 * 1000;
21
+ /**
22
+ * Allows you to retain a resource as part of a component lifecycle accounting
23
+ * for Suspense. You temporarily retain the resource during render, then
24
+ * permanently retain it during commit and release it during unmount.
25
+ */
26
+
27
+ var SuspenseResource = /*#__PURE__*/function () {
28
+ function SuspenseResource(retain) {
29
+ var _this = this;
30
+
31
+ (0, _defineProperty2["default"])(this, "_retainCount", 0);
32
+ (0, _defineProperty2["default"])(this, "_retainDisposable", null);
33
+ (0, _defineProperty2["default"])(this, "_releaseTemporaryRetain", null);
34
+
35
+ this._retain = function (environment) {
36
+ _this._retainCount++;
37
+
38
+ if (_this._retainCount === 1) {
39
+ _this._retainDisposable = retain(environment);
40
+ }
41
+
42
+ return {
43
+ dispose: function dispose() {
44
+ _this._retainCount = Math.max(0, _this._retainCount - 1);
45
+
46
+ if (_this._retainCount === 0) {
47
+ !(_this._retainDisposable != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected disposable to release query to be defined.' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
48
+
49
+ _this._retainDisposable.dispose();
50
+
51
+ _this._retainDisposable = null;
52
+ }
53
+ }
54
+ };
55
+ };
56
+ }
57
+
58
+ var _proto = SuspenseResource.prototype;
59
+
60
+ _proto.temporaryRetain = function temporaryRetain(environment) {
61
+ var _this2 = this;
62
+
63
+ var _this$_releaseTempora;
64
+
65
+ // If we're executing in a server environment, there's no need
66
+ // to create temporary retains, since the component will never commit.
67
+ if (environment.isServer()) {
68
+ return {
69
+ dispose: function dispose() {}
70
+ };
71
+ } // temporaryRetain is called during the render phase. However,
72
+ // given that we can't tell if this render will eventually commit or not,
73
+ // we create a timer to autodispose of this retain in case the associated
74
+ // component never commits.
75
+ // If the component /does/ commit, permanentRetain will clear this timeout
76
+ // and permanently retain the data.
77
+
78
+
79
+ var retention = this._retain(environment);
80
+
81
+ var releaseQueryTimeout = null;
82
+
83
+ var releaseTemporaryRetain = function releaseTemporaryRetain() {
84
+ clearTimeout(releaseQueryTimeout);
85
+ releaseQueryTimeout = null;
86
+ _this2._releaseTemporaryRetain = null;
87
+ retention.dispose();
88
+ };
89
+
90
+ releaseQueryTimeout = setTimeout(releaseTemporaryRetain, TEMPORARY_RETAIN_DURATION_MS); // NOTE: Since temporaryRetain can be called multiple times, we release
91
+ // the previous temporary retain after we re-establish a new one, since
92
+ // we only ever need a single temporary retain until the permanent retain is
93
+ // established.
94
+ // temporaryRetain may be called multiple times by React during the render
95
+ // phase, as well as multiple times by other query components that are
96
+ // rendering the same query/variables.
97
+
98
+ (_this$_releaseTempora = this._releaseTemporaryRetain) === null || _this$_releaseTempora === void 0 ? void 0 : _this$_releaseTempora.call(this);
99
+ this._releaseTemporaryRetain = releaseTemporaryRetain;
100
+ return {
101
+ dispose: function dispose() {
102
+ var _this$_releaseTempora2;
103
+
104
+ (_this$_releaseTempora2 = _this2._releaseTemporaryRetain) === null || _this$_releaseTempora2 === void 0 ? void 0 : _this$_releaseTempora2.call(_this2);
105
+ }
106
+ };
107
+ };
108
+
109
+ _proto.permanentRetain = function permanentRetain(environment) {
110
+ var disposable = this._retain(environment);
111
+
112
+ this.releaseTemporaryRetain();
113
+ return disposable;
114
+ };
115
+
116
+ _proto.releaseTemporaryRetain = function releaseTemporaryRetain() {
117
+ var _this$_releaseTempora3;
118
+
119
+ (_this$_releaseTempora3 = this._releaseTemporaryRetain) === null || _this$_releaseTempora3 === void 0 ? void 0 : _this$_releaseTempora3.call(this);
120
+ this._releaseTemporaryRetain = null;
121
+ };
122
+
123
+ _proto.getRetainCount = function getRetainCount() {
124
+ return this._retainCount;
125
+ };
126
+
127
+ return SuspenseResource;
128
+ }();
129
+
130
+ module.exports = SuspenseResource;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
3
  *
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.