react-relay 12.0.0 → 13.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 */