react-relay 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +47 -0
  3. package/ReactRelayContainerUtils.js.flow +1 -1
  4. package/ReactRelayContext.js +2 -2
  5. package/ReactRelayContext.js.flow +3 -4
  6. package/ReactRelayFragmentContainer.js.flow +11 -17
  7. package/ReactRelayFragmentMockRenderer.js.flow +2 -2
  8. package/ReactRelayLocalQueryRenderer.js.flow +7 -8
  9. package/ReactRelayPaginationContainer.js.flow +30 -40
  10. package/ReactRelayQueryFetcher.js.flow +10 -11
  11. package/ReactRelayQueryRenderer.js.flow +16 -16
  12. package/ReactRelayQueryRendererContext.js.flow +1 -1
  13. package/ReactRelayRefetchContainer.js.flow +25 -33
  14. package/ReactRelayTestMocker.js.flow +17 -15
  15. package/ReactRelayTypes.js.flow +11 -11
  16. package/RelayContext.js.flow +4 -4
  17. package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +2 -3
  18. package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +2 -3
  19. package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +2 -3
  20. package/__flowtests__/RelayModern-flowtest.js.flow +79 -47
  21. package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +6 -5
  22. package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +6 -5
  23. package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +5 -4
  24. package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +5 -4
  25. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +14 -11
  26. package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +14 -11
  27. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +14 -9
  28. package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +14 -11
  29. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +14 -9
  30. package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +14 -11
  31. package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +16 -13
  32. package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +16 -13
  33. package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +14 -11
  34. package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +14 -11
  35. package/assertFragmentMap.js.flow +3 -3
  36. package/buildReactRelayContainer.js.flow +12 -11
  37. package/getRootVariablesForFragments.js.flow +3 -5
  38. package/hooks.js +2 -2
  39. package/hooks.js.flow +4 -6
  40. package/index.js +2 -2
  41. package/index.js.flow +5 -7
  42. package/isRelayEnvironment.js.flow +1 -1
  43. package/jest-react/enqueueTask.js.flow +2 -2
  44. package/jest-react/index.js.flow +1 -1
  45. package/jest-react/internalAct.js.flow +2 -4
  46. package/legacy.js +2 -2
  47. package/legacy.js.flow +1 -1
  48. package/lib/ReactRelayContainerUtils.js +1 -1
  49. package/lib/ReactRelayContext.js +1 -1
  50. package/lib/ReactRelayFragmentContainer.js +5 -5
  51. package/lib/ReactRelayFragmentMockRenderer.js +3 -3
  52. package/lib/ReactRelayLocalQueryRenderer.js +8 -9
  53. package/lib/ReactRelayPaginationContainer.js +19 -23
  54. package/lib/ReactRelayQueryFetcher.js +3 -3
  55. package/lib/ReactRelayQueryRenderer.js +5 -5
  56. package/lib/ReactRelayQueryRendererContext.js +1 -1
  57. package/lib/ReactRelayRefetchContainer.js +13 -15
  58. package/lib/ReactRelayTestMocker.js +8 -9
  59. package/lib/ReactRelayTypes.js +1 -1
  60. package/lib/RelayContext.js +4 -3
  61. package/lib/assertFragmentMap.js +3 -2
  62. package/lib/buildReactRelayContainer.js +8 -8
  63. package/lib/getRootVariablesForFragments.js +2 -3
  64. package/lib/hooks.js +6 -6
  65. package/lib/index.js +8 -8
  66. package/lib/isRelayEnvironment.js +1 -1
  67. package/lib/jest-react/enqueueTask.js +1 -1
  68. package/lib/jest-react/internalAct.js +3 -4
  69. package/lib/legacy.js +1 -1
  70. package/lib/multi-actor/ActorChange.js +3 -3
  71. package/lib/multi-actor/index.js +1 -1
  72. package/lib/multi-actor/useRelayActorEnvironment.js +3 -3
  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 +242 -46
  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 +84 -5
  83. package/lib/relay-hooks/RelayEnvironmentProvider.js +1 -1
  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 +9 -10
  87. package/lib/relay-hooks/preloadQuery_DEPRECATED.js +25 -11
  88. package/lib/relay-hooks/prepareEntryPoint_DEPRECATED.js +1 -1
  89. package/lib/relay-hooks/useBlockingPaginationFragment.js +3 -3
  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 +5 -5
  99. package/lib/relay-hooks/useLoadMoreFunction.js +8 -10
  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 +1 -1
  104. package/lib/relay-hooks/usePreloadedQuery.js +6 -6
  105. package/lib/relay-hooks/useQueryLoader.js +5 -5
  106. package/lib/relay-hooks/useRefetchableFragment.js +1 -1
  107. package/lib/relay-hooks/useRefetchableFragmentNode.js +11 -13
  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 +1 -1
  112. package/multi-actor/ActorChange.js.flow +4 -5
  113. package/multi-actor/index.js.flow +1 -1
  114. package/multi-actor/useRelayActorEnvironment.js.flow +6 -8
  115. package/package.json +3 -3
  116. package/react-relay-hooks.js +2 -2
  117. package/react-relay-hooks.min.js +3 -3
  118. package/react-relay-legacy.js +2 -2
  119. package/react-relay-legacy.min.js +3 -3
  120. package/react-relay.js +2 -2
  121. package/react-relay.min.js +3 -3
  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 +19 -25
  125. package/relay-hooks/FragmentResource.js.flow +221 -35
  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 +120 -18
  132. package/relay-hooks/RelayEnvironmentProvider.js.flow +10 -10
  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 +23 -24
  145. package/relay-hooks/preloadQuery_DEPRECATED.js.flow +30 -14
  146. package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +7 -13
  147. package/relay-hooks/useBlockingPaginationFragment.js.flow +13 -14
  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 +12 -14
  157. package/relay-hooks/useLoadMoreFunction.js.flow +20 -28
  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 +38 -47
  162. package/relay-hooks/usePreloadedQuery.js.flow +14 -20
  163. package/relay-hooks/useQueryLoader.js.flow +14 -17
  164. package/relay-hooks/useRefetchableFragment.js.flow +8 -9
  165. package/relay-hooks/useRefetchableFragmentNode.js.flow +23 -31
  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 +7 -8
@@ -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.
@@ -13,19 +13,7 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- const LRUCache = require('./LRUCache');
17
-
18
- const invariant = require('invariant');
19
- const warning = require('warning');
20
-
21
- const {isPromise} = require('relay-runtime');
22
-
23
- const CACHE_CAPACITY = 1000;
24
-
25
- const DEFAULT_FETCH_POLICY = 'store-or-network';
26
-
27
- const DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
28
-
16
+ import type {Cache} from './LRUCache';
29
17
  import type {
30
18
  Disposable,
31
19
  FetchPolicy,
@@ -40,7 +28,15 @@ import type {
40
28
  Snapshot,
41
29
  Subscription,
42
30
  } from 'relay-runtime';
43
- import type {Cache} from './LRUCache';
31
+
32
+ const LRUCache = require('./LRUCache');
33
+ const SuspenseResource = require('./SuspenseResource');
34
+ const invariant = require('invariant');
35
+ const {RelayFeatureFlags, isPromise} = require('relay-runtime');
36
+ const warning = require('warning');
37
+
38
+ const CACHE_CAPACITY = 1000;
39
+ const DEFAULT_FETCH_POLICY = 'store-or-network';
44
40
 
45
41
  export type QueryResource = QueryResourceImpl;
46
42
 
@@ -63,7 +59,7 @@ type QueryResourceCacheEntry = {|
63
59
  permanentRetain(environment: IEnvironment): Disposable,
64
60
  releaseTemporaryRetain(): void,
65
61
  |};
66
- opaque type QueryResult: {
62
+ export opaque type QueryResult: {
67
63
  fragmentNode: ReaderFragment,
68
64
  fragmentRef: mixed,
69
65
  ...
@@ -129,6 +125,106 @@ function createCacheEntry(
129
125
  value: Error | Promise<void> | QueryResult,
130
126
  networkSubscription: ?Subscription,
131
127
  onDispose: QueryResourceCacheEntry => void,
128
+ ): QueryResourceCacheEntry {
129
+ // There should be no behavior difference between createCacheEntry_new and
130
+ // createCacheEntry_old, and it doesn't directly relate to Client Edges.
131
+ // It was just a refactoring that was needed for Client Edges but that
132
+ // is behind the feature flag just in case there is any accidental breakage.
133
+ if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
134
+ return createCacheEntry_new(
135
+ cacheIdentifier,
136
+ operation,
137
+ operationAvailability,
138
+ value,
139
+ networkSubscription,
140
+ onDispose,
141
+ );
142
+ } else {
143
+ return createCacheEntry_old(
144
+ cacheIdentifier,
145
+ operation,
146
+ operationAvailability,
147
+ value,
148
+ networkSubscription,
149
+ onDispose,
150
+ );
151
+ }
152
+ }
153
+
154
+ function createCacheEntry_new(
155
+ cacheIdentifier: string,
156
+ operation: OperationDescriptor,
157
+ operationAvailability: ?OperationAvailability,
158
+ value: Error | Promise<void> | QueryResult,
159
+ networkSubscription: ?Subscription,
160
+ onDispose: QueryResourceCacheEntry => void,
161
+ ): QueryResourceCacheEntry {
162
+ const isLiveQuery = operationIsLiveQuery(operation);
163
+
164
+ let currentValue: Error | Promise<void> | QueryResult = value;
165
+ let currentNetworkSubscription: ?Subscription = networkSubscription;
166
+
167
+ const suspenseResource = new SuspenseResource(environment => {
168
+ const retention = environment.retain(operation);
169
+ return {
170
+ dispose: () => {
171
+ // Normally if this entry never commits, the request would've ended by the
172
+ // time this timeout expires and the temporary retain is released. However,
173
+ // we need to do this for live queries which remain open indefinitely.
174
+ if (isLiveQuery && currentNetworkSubscription != null) {
175
+ currentNetworkSubscription.unsubscribe();
176
+ }
177
+ retention.dispose();
178
+ onDispose(cacheEntry);
179
+ },
180
+ };
181
+ });
182
+
183
+ const cacheEntry = {
184
+ cacheIdentifier,
185
+ id: nextID++,
186
+ processedPayloadsCount: 0,
187
+ operationAvailability,
188
+ getValue() {
189
+ return currentValue;
190
+ },
191
+ setValue(val: QueryResult | Promise<void> | Error) {
192
+ currentValue = val;
193
+ },
194
+ getRetainCount() {
195
+ return suspenseResource.getRetainCount();
196
+ },
197
+ getNetworkSubscription() {
198
+ return currentNetworkSubscription;
199
+ },
200
+ setNetworkSubscription(subscription: ?Subscription) {
201
+ if (isLiveQuery && currentNetworkSubscription != null) {
202
+ currentNetworkSubscription.unsubscribe();
203
+ }
204
+ currentNetworkSubscription = subscription;
205
+ },
206
+ temporaryRetain(environment: IEnvironment): Disposable {
207
+ return suspenseResource.temporaryRetain(environment);
208
+ },
209
+ permanentRetain(environment: IEnvironment): Disposable {
210
+ return suspenseResource.permanentRetain(environment);
211
+ },
212
+ releaseTemporaryRetain() {
213
+ suspenseResource.releaseTemporaryRetain();
214
+ },
215
+ };
216
+
217
+ return cacheEntry;
218
+ }
219
+
220
+ const DATA_RETENTION_TIMEOUT = 5 * 60 * 1000;
221
+ function createCacheEntry_old(
222
+ cacheIdentifier: string,
223
+ operation: OperationDescriptor,
224
+ operationAvailability: ?OperationAvailability,
225
+ value: Error | Promise<void> | QueryResult,
226
+ networkSubscription: ?Subscription,
227
+ onDispose: QueryResourceCacheEntry => void,
132
228
  ): QueryResourceCacheEntry {
133
229
  const isLiveQuery = operationIsLiveQuery(operation);
134
230
 
@@ -168,7 +264,7 @@ function createCacheEntry(
168
264
  getValue() {
169
265
  return currentValue;
170
266
  },
171
- setValue(val) {
267
+ setValue(val: QueryResult | Promise<void> | Error) {
172
268
  currentValue = val;
173
269
  },
174
270
  getRetainCount() {
@@ -436,8 +532,14 @@ class QueryResourceImpl {
436
532
  }
437
533
 
438
534
  _clearCacheEntry = (cacheEntry: QueryResourceCacheEntry): void => {
439
- if (cacheEntry.getRetainCount() <= 0) {
535
+ // The new code does this retainCount <= 0 check within SuspenseResource
536
+ // before calling _clearCacheEntry, whereas with the old code we do it here.
537
+ if (RelayFeatureFlags.REFACTOR_SUSPENSE_RESOURCE) {
440
538
  this._cache.delete(cacheEntry.cacheIdentifier);
539
+ } else {
540
+ if (cacheEntry.getRetainCount() <= 0) {
541
+ this._cache.delete(cacheEntry.cacheIdentifier);
542
+ }
441
543
  }
442
544
  };
443
545
 
@@ -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.
@@ -13,14 +13,14 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- const React = require('react');
17
- const ReactRelayContext = require('react-relay/ReactRelayContext');
18
-
16
+ import type {IEnvironment} from 'relay-runtime';
19
17
  import type {
20
- IActorEnvironment,
21
18
  ActorIdentifier,
19
+ IActorEnvironment,
22
20
  } from 'relay-runtime/multi-actor-environment';
23
- import type {IEnvironment} from 'relay-runtime';
21
+
22
+ const React = require('react');
23
+ const ReactRelayContext = require('react-relay/ReactRelayContext');
24
24
 
25
25
  const {useMemo} = React;
26
26
 
@@ -34,10 +34,10 @@ type Props = $ReadOnly<{|
34
34
 
35
35
  function RelayEnvironmentProvider(props: Props): React.Node {
36
36
  const {children, environment, getEnvironmentForActor} = props;
37
- const context = useMemo(() => ({environment, getEnvironmentForActor}), [
38
- environment,
39
- getEnvironmentForActor,
40
- ]);
37
+ const context = useMemo(
38
+ () => ({environment, getEnvironmentForActor}),
39
+ [environment, getEnvironmentForActor],
40
+ );
41
41
  return (
42
42
  <ReactRelayContext.Provider value={context}>
43
43
  {children}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict-local
8
+ * @emails oncall+relay
9
+ * @format
10
+ */
11
+
12
+ // flowlint ambiguous-object-type:error
13
+
14
+ 'use strict';
15
+
16
+ import type {Disposable, IEnvironment} from 'relay-runtime';
17
+
18
+ const invariant = require('invariant');
19
+
20
+ const TEMPORARY_RETAIN_DURATION_MS = 5 * 60 * 1000;
21
+
22
+ /**
23
+ * Allows you to retain a resource as part of a component lifecycle accounting
24
+ * for Suspense. You temporarily retain the resource during render, then
25
+ * permanently retain it during commit and release it during unmount.
26
+ */
27
+ class SuspenseResource {
28
+ _retainCount = 0;
29
+ _retainDisposable: ?Disposable = null;
30
+ _releaseTemporaryRetain: ?() => void = null;
31
+ _retain: IEnvironment => Disposable;
32
+
33
+ constructor(retain: (environment: IEnvironment) => Disposable) {
34
+ this._retain = (environment: IEnvironment): Disposable => {
35
+ this._retainCount++;
36
+ if (this._retainCount === 1) {
37
+ this._retainDisposable = retain(environment);
38
+ }
39
+ return {
40
+ dispose: () => {
41
+ this._retainCount = Math.max(0, this._retainCount - 1);
42
+ if (this._retainCount === 0) {
43
+ invariant(
44
+ this._retainDisposable != null,
45
+ 'Relay: Expected disposable to release query to be defined.' +
46
+ "If you're seeing this, this is likely a bug in Relay.",
47
+ );
48
+ this._retainDisposable.dispose();
49
+ this._retainDisposable = null;
50
+ }
51
+ },
52
+ };
53
+ };
54
+ }
55
+
56
+ temporaryRetain(environment: IEnvironment): Disposable {
57
+ // If we're executing in a server environment, there's no need
58
+ // to create temporary retains, since the component will never commit.
59
+ if (environment.isServer()) {
60
+ return {dispose: () => {}};
61
+ }
62
+
63
+ // temporaryRetain is called during the render phase. However,
64
+ // given that we can't tell if this render will eventually commit or not,
65
+ // we create a timer to autodispose of this retain in case the associated
66
+ // component never commits.
67
+ // If the component /does/ commit, permanentRetain will clear this timeout
68
+ // and permanently retain the data.
69
+ const retention = this._retain(environment);
70
+ let releaseQueryTimeout = null;
71
+ const releaseTemporaryRetain = () => {
72
+ clearTimeout(releaseQueryTimeout);
73
+ releaseQueryTimeout = null;
74
+ this._releaseTemporaryRetain = null;
75
+ retention.dispose();
76
+ };
77
+ releaseQueryTimeout = setTimeout(
78
+ releaseTemporaryRetain,
79
+ TEMPORARY_RETAIN_DURATION_MS,
80
+ );
81
+
82
+ // NOTE: Since temporaryRetain can be called multiple times, we release
83
+ // the previous temporary retain after we re-establish a new one, since
84
+ // we only ever need a single temporary retain until the permanent retain is
85
+ // established.
86
+ // temporaryRetain may be called multiple times by React during the render
87
+ // phase, as well as multiple times by other query components that are
88
+ // rendering the same query/variables.
89
+ this._releaseTemporaryRetain?.();
90
+ this._releaseTemporaryRetain = releaseTemporaryRetain;
91
+
92
+ return {
93
+ dispose: () => {
94
+ this._releaseTemporaryRetain?.();
95
+ },
96
+ };
97
+ }
98
+
99
+ permanentRetain(environment: IEnvironment): Disposable {
100
+ const disposable = this._retain(environment);
101
+ this.releaseTemporaryRetain();
102
+ return disposable;
103
+ }
104
+
105
+ releaseTemporaryRetain(): void {
106
+ this._releaseTemporaryRetain?.();
107
+ this._releaseTemporaryRetain = null;
108
+ }
109
+
110
+ getRetainCount(): number {
111
+ return this._retainCount;
112
+ }
113
+ }
114
+
115
+ 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.
@@ -13,8 +13,8 @@
13
13
 
14
14
  import type {
15
15
  EntryPoint,
16
- EntryPointProps,
17
16
  EntryPointElementConfig,
17
+ EntryPointProps,
18
18
  } from '../../EntryPointTypes.flow';
19
19
 
20
20
  type MyComponentOtherProps = $ReadOnly<{|
@@ -30,10 +30,11 @@ type PreloadParams = $ReadOnly<{||}>;
30
30
  type MyComponentEntryPointType = EntryPoint<PreloadParams, typeof MyComponent>;
31
31
 
32
32
  // This gets the "other props" of the component through the entrypoint's typing
33
- type MyComponentEntryPointProps = EntryPointElementConfig<MyComponentEntryPointType>;
33
+ type MyComponentEntryPointProps =
34
+ EntryPointElementConfig<MyComponentEntryPointType>;
34
35
 
35
36
  // This gets the "other props" directly from the component's prop typings
36
- type OtherProps = $PropertyType<MyComponentProps, 'props'>;
37
+ type OtherProps = MyComponentProps['props'];
37
38
 
38
39
  // We want to make sure that `OtherProps` and `MyComponentEntryPointProps` are exactly the same.
39
40
  opaque type __SUBTYPE_CHECK_1__: OtherProps = MyComponentEntryPointProps;
@@ -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,12 +11,12 @@
11
11
 
12
12
  'use strict';
13
13
 
14
+ import type {JSResourceReference} from 'JSResourceReference';
14
15
  import type {
15
16
  EntryPoint,
16
17
  EntryPointProps,
17
18
  PreloadedEntryPoint,
18
19
  } from '../../EntryPointTypes.flow';
19
- import type {JSResourceReference} from 'JSResourceReference';
20
20
 
21
21
  declare function mockJSResource<TModule>(
22
22
  module: TModule,
@@ -0,0 +1,59 @@
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
+ * @generated SignedSource<<57e35620e0558adaa97ee6b06423e705>>
8
+ * @flow
9
+ * @lightSyntaxTransform
10
+ * @nogrep
11
+ */
12
+
13
+ /* eslint-disable */
14
+
15
+ 'use strict';
16
+
17
+ /*::
18
+ import type { Fragment, ReaderFragment } from 'relay-runtime';
19
+ import type { FragmentType } from "relay-runtime";
20
+ declare export opaque type useFragmentFlowtest_user$fragmentType: FragmentType;
21
+ export type useFragmentFlowtest_user$ref = useFragmentFlowtest_user$fragmentType;
22
+ export type useFragmentFlowtest_user$data = {|
23
+ +id: string,
24
+ +$fragmentType: useFragmentFlowtest_user$fragmentType,
25
+ |};
26
+ export type useFragmentFlowtest_user = useFragmentFlowtest_user$data;
27
+ export type useFragmentFlowtest_user$key = {
28
+ +$data?: useFragmentFlowtest_user$data,
29
+ +$fragmentSpreads: useFragmentFlowtest_user$fragmentType,
30
+ ...
31
+ };
32
+ */
33
+
34
+ var node/*: ReaderFragment*/ = {
35
+ "argumentDefinitions": [],
36
+ "kind": "Fragment",
37
+ "metadata": null,
38
+ "name": "useFragmentFlowtest_user",
39
+ "selections": [
40
+ {
41
+ "alias": null,
42
+ "args": null,
43
+ "kind": "ScalarField",
44
+ "name": "id",
45
+ "storageKey": null
46
+ }
47
+ ],
48
+ "type": "User",
49
+ "abstractKey": null
50
+ };
51
+
52
+ if (__DEV__) {
53
+ (node/*: any*/).hash = "a0eb71a1bbfb0eb3a4c42fb5a69a7f81";
54
+ }
55
+
56
+ module.exports = ((node/*: any*/)/*: Fragment<
57
+ useFragmentFlowtest_user$fragmentType,
58
+ useFragmentFlowtest_user$data,
59
+ >*/);
@@ -0,0 +1,61 @@
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
+ * @generated SignedSource<<e21003870360e15cc93c1cee7aa239ad>>
8
+ * @flow
9
+ * @lightSyntaxTransform
10
+ * @nogrep
11
+ */
12
+
13
+ /* eslint-disable */
14
+
15
+ 'use strict';
16
+
17
+ /*::
18
+ import type { Fragment, ReaderFragment } from 'relay-runtime';
19
+ import type { FragmentType } from "relay-runtime";
20
+ declare export opaque type useFragmentFlowtest_users$fragmentType: FragmentType;
21
+ export type useFragmentFlowtest_users$ref = useFragmentFlowtest_users$fragmentType;
22
+ export type useFragmentFlowtest_users$data = $ReadOnlyArray<{|
23
+ +id: string,
24
+ +$fragmentType: useFragmentFlowtest_users$fragmentType,
25
+ |}>;
26
+ export type useFragmentFlowtest_users = useFragmentFlowtest_users$data;
27
+ export type useFragmentFlowtest_users$key = $ReadOnlyArray<{
28
+ +$data?: useFragmentFlowtest_users$data,
29
+ +$fragmentSpreads: useFragmentFlowtest_users$fragmentType,
30
+ ...
31
+ }>;
32
+ */
33
+
34
+ var node/*: ReaderFragment*/ = {
35
+ "argumentDefinitions": [],
36
+ "kind": "Fragment",
37
+ "metadata": {
38
+ "plural": true
39
+ },
40
+ "name": "useFragmentFlowtest_users",
41
+ "selections": [
42
+ {
43
+ "alias": null,
44
+ "args": null,
45
+ "kind": "ScalarField",
46
+ "name": "id",
47
+ "storageKey": null
48
+ }
49
+ ],
50
+ "type": "User",
51
+ "abstractKey": null
52
+ };
53
+
54
+ if (__DEV__) {
55
+ (node/*: any*/).hash = "8b9b9b23494aec63a7cb96eed58ebcbc";
56
+ }
57
+
58
+ module.exports = ((node/*: any*/)/*: Fragment<
59
+ useFragmentFlowtest_users$fragmentType,
60
+ useFragmentFlowtest_users$data,
61
+ >*/);
@@ -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,16 +11,7 @@
11
11
 
12
12
  // flowlint ambiguous-object-type:error
13
13
 
14
- import useBlockingPaginationFragment from '../useBlockingPaginationFragment';
15
14
  import type {LoadMoreFn} from '../useLoadMoreFunction';
16
- import {
17
- fragmentData,
18
- fragmentInput,
19
- keyAnotherNonNullable,
20
- keyAnotherNullable,
21
- keyNonNullable,
22
- keyNullable,
23
- } from './utils';
24
15
  import type {
25
16
  FetchFn,
26
17
  NonNullableData,
@@ -31,6 +22,16 @@ import type {
31
22
  } from './utils';
32
23
  import type {IEnvironment, OperationType} from 'relay-runtime';
33
24
 
25
+ import useBlockingPaginationFragment from '../useBlockingPaginationFragment';
26
+ import {
27
+ fragmentData,
28
+ fragmentInput,
29
+ keyAnotherNonNullable,
30
+ keyAnotherNullable,
31
+ keyNonNullable,
32
+ keyNullable,
33
+ } from './utils';
34
+
34
35
  type ExpectedReturnType<
35
36
  TQuery: OperationType,
36
37
  TQueryVariables,
@@ -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,52 +11,75 @@
11
11
 
12
12
  // flowlint ambiguous-object-type:error
13
13
 
14
- import useFragment from '../useFragment';
15
- import {
16
- fragmentInput,
17
- keyAnotherNonNullable,
18
- keyAnotherNullable,
19
- keyNonNullable,
20
- keyNonNullablePlural,
21
- keyNullable,
22
- keyNullablePlural,
23
- fragmentData,
24
- } from './utils';
25
14
  import type {
26
- NonNullableData,
27
- NonNullablePluralData,
28
- NullableData,
29
- NullablePluralData,
30
- } from './utils';
15
+ useFragmentFlowtest_user$data,
16
+ useFragmentFlowtest_user$key,
17
+ } from './__generated__/useFragmentFlowtest_user.graphql';
18
+ import typeof useFragmentFlowtest_user$fragment from './__generated__/useFragmentFlowtest_user.graphql';
19
+ import type {
20
+ useFragmentFlowtest_users$data,
21
+ useFragmentFlowtest_users$key,
22
+ } from './__generated__/useFragmentFlowtest_users.graphql';
23
+ import typeof useFragmentFlowtest_users$fragment from './__generated__/useFragmentFlowtest_users.graphql';
24
+
25
+ import useFragment from '../useFragment';
26
+ import {graphql} from 'relay-runtime';
27
+
28
+ declare var Any: $FlowFixMe;
29
+
30
+ const userFragment: useFragmentFlowtest_user$fragment = graphql`
31
+ fragment useFragmentFlowtest_user on User {
32
+ id
33
+ }
34
+ `;
35
+
36
+ const usersFragment: useFragmentFlowtest_users$fragment = graphql`
37
+ fragment useFragmentFlowtest_users on User @relay(plural: true) {
38
+ id
39
+ }
40
+ `;
31
41
 
32
42
  /* eslint-disable react-hooks/rules-of-hooks */
33
43
 
34
44
  // Nullability of returned data type is correct
35
- (useFragment(fragmentInput, keyNonNullable): NonNullableData);
36
- (useFragment(fragmentInput, keyNullable): NullableData);
37
- (useFragment(fragmentInput, keyNonNullablePlural): NonNullablePluralData);
38
- (useFragment(fragmentInput, keyNullablePlural): NullablePluralData);
45
+ (useFragment(
46
+ userFragment,
47
+ (Any: useFragmentFlowtest_user$key),
48
+ ): useFragmentFlowtest_user$data);
49
+ (useFragment(
50
+ userFragment,
51
+ (Any: ?useFragmentFlowtest_user$key),
52
+ ): ?useFragmentFlowtest_user$data);
53
+ (useFragment(
54
+ usersFragment,
55
+ (Any: useFragmentFlowtest_users$key),
56
+ ): useFragmentFlowtest_users$data);
57
+ (useFragment(
58
+ usersFragment,
59
+ (Any: ?useFragmentFlowtest_users$key),
60
+ ): ?useFragmentFlowtest_users$data);
39
61
 
40
62
  // $FlowExpectedError: can't cast nullable to non-nullable
41
- (useFragment(fragmentInput, keyNullable): NonNullableData);
63
+ (useFragment(
64
+ userFragment,
65
+ (Any: ?useFragmentFlowtest_user$key),
66
+ ): useFragmentFlowtest_user$data);
42
67
  // $FlowExpectedError: can't cast nullable plural to non-nullable plural
43
- (useFragment(fragmentInput, keyNullablePlural): NonNullablePluralData);
44
-
45
- // $FlowExpectedError: actual type of returned data is correct
46
- (useFragment(fragmentInput, keyAnotherNonNullable): NonNullableData);
47
- // $FlowExpectedError
48
- (useFragment(fragmentInput, keyAnotherNullable): NullableData);
68
+ (useFragment(
69
+ usersFragment,
70
+ (Any: ?useFragmentFlowtest_users$key),
71
+ ): useFragmentFlowtest_users$data);
49
72
 
50
73
  // $FlowExpectedError: Key should be one of the generated types
51
- (useFragment(fragmentInput, 'INVALID_KEY'): NullableData);
74
+ useFragment(userFragment, 'INVALID_KEY');
52
75
 
53
76
  // $FlowExpectedError: Key should not be a user provided object
54
- useFragment(fragmentInput, {a: 123});
77
+ useFragment(userFragment, {a: 123});
55
78
 
56
79
  // $FlowExpectedError: Key should not be an empty object
57
- useFragment(fragmentInput, {});
80
+ useFragment(userFragment, {});
58
81
 
59
82
  // $FlowExpectedError: Key should be the `<name>$key` type from generated flow
60
- useFragment(fragmentInput, fragmentData);
83
+ useFragment(userFragment, (Any: useFragmentFlowtest_user$data));
61
84
 
62
85
  /* eslint-enable react-hooks/rules-of-hooks */