react-relay 11.0.1 → 13.0.0-rc.1
Sign up to get free protection for your applications and to get access to all the features.
- package/ReactRelayContext.js +1 -1
- package/ReactRelayContext.js.flow +2 -3
- package/ReactRelayFragmentContainer.js.flow +24 -24
- package/ReactRelayFragmentMockRenderer.js.flow +1 -1
- package/ReactRelayLocalQueryRenderer.js.flow +6 -7
- package/ReactRelayPaginationContainer.js.flow +111 -58
- package/ReactRelayQueryFetcher.js.flow +9 -10
- package/ReactRelayQueryRenderer.js.flow +115 -81
- package/ReactRelayRefetchContainer.js.flow +41 -38
- package/ReactRelayTestMocker.js.flow +16 -14
- package/ReactRelayTypes.js.flow +10 -10
- package/RelayContext.js.flow +3 -3
- package/__flowtests__/ReactRelayFragmentContainer-flowtest.js.flow +1 -2
- package/__flowtests__/ReactRelayPaginationContainer-flowtest.js.flow +11 -7
- package/__flowtests__/ReactRelayRefetchContainer-flowtest.js.flow +10 -6
- package/__flowtests__/RelayModern-flowtest.js.flow +78 -46
- package/__flowtests__/RelayModernFlowtest_badref.graphql.js.flow +5 -4
- package/__flowtests__/RelayModernFlowtest_notref.graphql.js.flow +5 -4
- package/__flowtests__/RelayModernFlowtest_user.graphql.js.flow +4 -3
- package/__flowtests__/RelayModernFlowtest_users.graphql.js.flow +4 -3
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer.graphql.js.flow +72 -0
- package/__flowtests__/__generated__/ReactRelayFragmentContainerFlowtest_viewer2.graphql.js.flow +72 -0
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtestQuery.graphql.js.flow +227 -0
- package/__flowtests__/__generated__/ReactRelayPaginationContainerFlowtest_viewer.graphql.js.flow +164 -0
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtestQuery.graphql.js.flow +227 -0
- package/__flowtests__/__generated__/ReactRelayRefetchContainerFlowtest_viewer.graphql.js.flow +164 -0
- package/__flowtests__/__generated__/RelayModernFlowtest_badref.graphql.js.flow +66 -0
- package/__flowtests__/__generated__/RelayModernFlowtest_notref.graphql.js.flow +66 -0
- package/__flowtests__/__generated__/RelayModernFlowtest_user.graphql.js.flow +59 -0
- package/__flowtests__/__generated__/RelayModernFlowtest_users.graphql.js.flow +61 -0
- package/assertFragmentMap.js.flow +2 -2
- package/buildReactRelayContainer.js.flow +15 -12
- package/getRootVariablesForFragments.js.flow +2 -4
- package/hooks.js +1 -1
- package/hooks.js.flow +5 -6
- package/index.js +1 -1
- package/index.js.flow +6 -7
- package/jest-react/enqueueTask.js.flow +56 -0
- package/jest-react/index.js.flow +12 -0
- package/jest-react/internalAct.js.flow +139 -0
- package/legacy.js +1 -1
- package/lib/ReactRelayFragmentContainer.js +21 -15
- package/lib/ReactRelayFragmentMockRenderer.js +2 -2
- package/lib/ReactRelayLocalQueryRenderer.js +7 -8
- package/lib/ReactRelayPaginationContainer.js +96 -38
- package/lib/ReactRelayQueryFetcher.js +3 -3
- package/lib/ReactRelayQueryRenderer.js +86 -53
- package/lib/ReactRelayRefetchContainer.js +38 -25
- package/lib/ReactRelayTestMocker.js +8 -9
- package/lib/RelayContext.js +3 -2
- package/lib/assertFragmentMap.js +3 -2
- package/lib/buildReactRelayContainer.js +14 -11
- package/lib/getRootVariablesForFragments.js +1 -2
- package/lib/hooks.js +5 -5
- package/lib/index.js +7 -7
- package/lib/jest-react/enqueueTask.js +53 -0
- package/lib/jest-react/index.js +13 -0
- package/lib/jest-react/internalAct.js +116 -0
- package/lib/multi-actor/ActorChange.js +30 -0
- package/lib/multi-actor/index.js +11 -0
- package/lib/multi-actor/useRelayActorEnvironment.js +29 -0
- package/lib/relay-hooks/EntryPointContainer.react.js +3 -3
- package/lib/relay-hooks/FragmentResource.js +347 -92
- package/lib/relay-hooks/LRUCache.js +1 -1
- package/lib/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js +4 -4
- package/lib/relay-hooks/MatchContainer.js +1 -1
- package/lib/relay-hooks/QueryResource.js +172 -29
- package/lib/relay-hooks/RelayEnvironmentProvider.js +5 -3
- package/lib/relay-hooks/SuspenseResource.js +130 -0
- package/lib/relay-hooks/loadQuery.js +42 -20
- package/lib/relay-hooks/preloadQuery_DEPRECATED.js +24 -15
- package/lib/relay-hooks/useBlockingPaginationFragment.js +4 -5
- package/lib/relay-hooks/useEntryPointLoader.js +2 -2
- package/lib/relay-hooks/useFetchTrackingRef.js +2 -1
- package/lib/relay-hooks/useFragment.js +8 -7
- package/lib/relay-hooks/useFragmentNode.js +4 -4
- package/lib/relay-hooks/useIsOperationNodeActive.js +3 -3
- package/lib/relay-hooks/useLazyLoadQuery.js +3 -3
- package/lib/relay-hooks/useLazyLoadQueryNode.js +10 -4
- package/lib/relay-hooks/useLoadMoreFunction.js +8 -12
- package/lib/relay-hooks/useMemoOperationDescriptor.js +2 -2
- package/lib/relay-hooks/useMemoVariables.js +2 -2
- package/lib/relay-hooks/useMutation.js +17 -6
- package/lib/relay-hooks/usePaginationFragment.js +2 -3
- package/lib/relay-hooks/usePreloadedQuery.js +8 -7
- package/lib/relay-hooks/useQueryLoader.js +30 -10
- package/lib/relay-hooks/useRefetchableFragmentNode.js +13 -17
- package/lib/relay-hooks/useRelayEnvironment.js +3 -3
- package/lib/relay-hooks/useStaticFragmentNodeWarning.js +2 -2
- package/lib/relay-hooks/useSubscribeToInvalidationState.js +2 -1
- package/lib/relay-hooks/useSubscription.js +10 -7
- package/multi-actor/ActorChange.js.flow +58 -0
- package/multi-actor/index.js.flow +14 -0
- package/multi-actor/useRelayActorEnvironment.js.flow +49 -0
- package/package.json +3 -2
- package/react-relay-hooks.js +2 -2
- package/react-relay-hooks.min.js +2 -2
- package/react-relay-legacy.js +2 -2
- package/react-relay-legacy.min.js +2 -2
- package/react-relay.js +2 -2
- package/react-relay.min.js +2 -2
- package/relay-hooks/EntryPointContainer.react.js.flow +8 -15
- package/relay-hooks/EntryPointTypes.flow.js.flow +24 -25
- package/relay-hooks/FragmentResource.js.flow +368 -94
- package/relay-hooks/LazyLoadEntryPointContainer_DEPRECATED.react.js.flow +32 -46
- package/relay-hooks/MatchContainer.js.flow +3 -2
- package/relay-hooks/QueryResource.js.flow +216 -25
- package/relay-hooks/RelayEnvironmentProvider.js.flow +14 -4
- package/relay-hooks/SuspenseResource.js.flow +115 -0
- package/relay-hooks/__flowtests__/EntryPointTypes/EntryPointElementConfig-flowtest.js.flow +4 -3
- package/relay-hooks/__flowtests__/EntryPointTypes/NestedEntrypoints-flowtest.js.flow +1 -1
- package/relay-hooks/__flowtests__/useBlockingPaginationFragment-flowtest.js.flow +10 -9
- package/relay-hooks/__flowtests__/useFragment-flowtest.js.flow +8 -7
- package/relay-hooks/__flowtests__/usePaginationFragment-flowtest.js.flow +10 -9
- package/relay-hooks/__flowtests__/useRefetchableFragment-flowtest.js.flow +10 -9
- package/relay-hooks/__flowtests__/utils.js.flow +8 -12
- package/relay-hooks/loadEntryPoint.js.flow +6 -12
- package/relay-hooks/loadQuery.js.flow +49 -31
- package/relay-hooks/preloadQuery_DEPRECATED.js.flow +30 -21
- package/relay-hooks/prepareEntryPoint_DEPRECATED.js.flow +6 -12
- package/relay-hooks/useBlockingPaginationFragment.js.flow +13 -11
- package/relay-hooks/useEntryPointLoader.js.flow +7 -10
- package/relay-hooks/useFetchTrackingRef.js.flow +2 -2
- package/relay-hooks/useFragment.js.flow +26 -46
- package/relay-hooks/useFragmentNode.js.flow +5 -7
- package/relay-hooks/useIsOperationNodeActive.js.flow +3 -5
- package/relay-hooks/useIsParentQueryActive.js.flow +3 -4
- package/relay-hooks/useLazyLoadQuery.js.flow +9 -10
- package/relay-hooks/useLazyLoadQueryNode.js.flow +19 -13
- package/relay-hooks/useLoadMoreFunction.js.flow +20 -29
- package/relay-hooks/useMemoOperationDescriptor.js.flow +5 -7
- package/relay-hooks/useMemoVariables.js.flow +6 -6
- package/relay-hooks/useMutation.js.flow +26 -26
- package/relay-hooks/usePaginationFragment.js.flow +38 -44
- package/relay-hooks/usePreloadedQuery.js.flow +18 -14
- package/relay-hooks/useQueryLoader.js.flow +41 -22
- package/relay-hooks/useRefetchableFragment.js.flow +7 -8
- package/relay-hooks/useRefetchableFragmentNode.js.flow +24 -32
- package/relay-hooks/useRelayEnvironment.js.flow +2 -4
- package/relay-hooks/useStaticFragmentNodeWarning.js.flow +2 -3
- package/relay-hooks/useSubscribeToInvalidationState.js.flow +3 -6
- package/relay-hooks/useSubscription.js.flow +20 -10
- package/lib/relay-hooks/getPaginationMetadata.js +0 -41
- package/lib/relay-hooks/getPaginationVariables.js +0 -67
- package/lib/relay-hooks/getRefetchMetadata.js +0 -36
- package/lib/relay-hooks/getValueAtPath.js +0 -51
- package/relay-hooks/getPaginationMetadata.js.flow +0 -74
- package/relay-hooks/getPaginationVariables.js.flow +0 -110
- package/relay-hooks/getRefetchMetadata.js.flow +0 -80
- package/relay-hooks/getValueAtPath.js.flow +0 -46
@@ -11,14 +11,14 @@
|
|
11
11
|
// flowlint ambiguous-object-type:error
|
12
12
|
'use strict';
|
13
13
|
|
14
|
-
var ProfilerContext = require('./ProfilerContext');
|
15
|
-
|
16
|
-
var React = require('react');
|
17
|
-
|
18
14
|
var preloadQuery_DEPRECATED = require('./preloadQuery_DEPRECATED');
|
19
15
|
|
16
|
+
var ProfilerContext = require('./ProfilerContext');
|
17
|
+
|
20
18
|
var useRelayEnvironment = require('./useRelayEnvironment');
|
21
19
|
|
20
|
+
var React = require('react');
|
21
|
+
|
22
22
|
var _require = require('react'),
|
23
23
|
useContext = _require.useContext,
|
24
24
|
useEffect = _require.useEffect,
|
@@ -98,7 +98,7 @@ function MatchContainer(_ref2) {
|
|
98
98
|
|
99
99
|
if (match != null && typeof match !== 'object') {
|
100
100
|
throw new Error('MatchContainer: Expected `match` value to be an object or null/undefined.');
|
101
|
-
} // NOTE: the MatchPointer type has a $
|
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
|
@@ -19,16 +19,24 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
|
|
19
19
|
|
20
20
|
var LRUCache = require('./LRUCache');
|
21
21
|
|
22
|
-
var
|
22
|
+
var SuspenseResource = require('./SuspenseResource');
|
23
|
+
|
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
|
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
|
-
|
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 (
|
151
|
-
|
232
|
+
if (_releaseTemporaryRetain != null) {
|
233
|
+
_releaseTemporaryRetain();
|
152
234
|
}
|
153
235
|
|
154
|
-
|
236
|
+
_releaseTemporaryRetain = localReleaseTemporaryRetain;
|
155
237
|
return {
|
156
238
|
dispose: function dispose() {
|
157
|
-
|
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 (
|
165
|
-
|
166
|
-
|
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
|
-
|
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)
|
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
|
-
|
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
|
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
|
-
|
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
|
}
|
@@ -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) Facebook, Inc. and its 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;
|
@@ -14,21 +14,21 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
14
14
|
|
15
15
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
16
16
|
|
17
|
-
var
|
18
|
-
|
19
|
-
var invariant = require("fbjs/lib/invariant");
|
17
|
+
var invariant = require('invariant');
|
20
18
|
|
21
|
-
var
|
19
|
+
var React = require('react');
|
22
20
|
|
23
21
|
var _require = require('relay-runtime'),
|
22
|
+
Observable = _require.Observable,
|
24
23
|
PreloadableQueryRegistry = _require.PreloadableQueryRegistry,
|
24
|
+
RelayFeatureFlags = _require.RelayFeatureFlags,
|
25
25
|
ReplaySubject = _require.ReplaySubject,
|
26
|
+
fetchQueryDeduped = _require.__internal.fetchQueryDeduped,
|
26
27
|
createOperationDescriptor = _require.createOperationDescriptor,
|
27
28
|
getRequest = _require.getRequest,
|
28
|
-
getRequestIdentifier = _require.getRequestIdentifier
|
29
|
-
|
30
|
-
|
31
|
-
fetchQueryDeduped = _require.__internal.fetchQueryDeduped;
|
29
|
+
getRequestIdentifier = _require.getRequestIdentifier;
|
30
|
+
|
31
|
+
var warning = require("fbjs/lib/warning");
|
32
32
|
|
33
33
|
var RenderDispatcher = null;
|
34
34
|
var fetchKey = 100001;
|
@@ -252,10 +252,9 @@ function loadQuery(environment, preloadableRequest, variables, options, environm
|
|
252
252
|
// ast, and we know that if we don't have the query ast
|
253
253
|
// available, then this query could've never been written to the
|
254
254
|
// store in the first place, so it couldn't have been cached.
|
255
|
-
var networkObservable = fetchPolicy === 'store-only' ? null : makeNetworkRequest(params);
|
255
|
+
var networkObservable = fetchPolicy === 'store-only' ? null : makeNetworkRequest(params); // $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
256
256
|
|
257
|
-
var _PreloadableQueryRegi = PreloadableQueryRegistry.onLoad(
|
258
|
-
queryId, function (preloadedModule) {
|
257
|
+
var _PreloadableQueryRegi = PreloadableQueryRegistry.onLoad(queryId, function (preloadedModule) {
|
259
258
|
cancelOnLoadCallback();
|
260
259
|
var operation = createOperationDescriptor(preloadedModule, variables, networkCacheConfig);
|
261
260
|
retainReference = environment.retain(operation);
|
@@ -278,6 +277,33 @@ function loadQuery(environment, preloadableRequest, variables, options, environm
|
|
278
277
|
}
|
279
278
|
|
280
279
|
var isDisposed = false;
|
280
|
+
var isReleased = false;
|
281
|
+
var isNetworkRequestCancelled = false;
|
282
|
+
|
283
|
+
var releaseQuery = function releaseQuery() {
|
284
|
+
if (isReleased) {
|
285
|
+
return;
|
286
|
+
}
|
287
|
+
|
288
|
+
retainReference && retainReference.dispose();
|
289
|
+
isReleased = true;
|
290
|
+
};
|
291
|
+
|
292
|
+
var cancelNetworkRequest = function cancelNetworkRequest() {
|
293
|
+
if (isNetworkRequestCancelled) {
|
294
|
+
return;
|
295
|
+
}
|
296
|
+
|
297
|
+
if (didExecuteNetworkSource) {
|
298
|
+
unsubscribeFromExecution && unsubscribeFromExecution();
|
299
|
+
} else {
|
300
|
+
unsubscribeFromNetworkRequest && unsubscribeFromNetworkRequest();
|
301
|
+
}
|
302
|
+
|
303
|
+
cancelOnLoadCallback && cancelOnLoadCallback();
|
304
|
+
isNetworkRequestCancelled = true;
|
305
|
+
};
|
306
|
+
|
281
307
|
return {
|
282
308
|
kind: 'PreloadedQuery',
|
283
309
|
environment: environment,
|
@@ -287,22 +313,18 @@ function loadQuery(environment, preloadableRequest, variables, options, environm
|
|
287
313
|
return;
|
288
314
|
}
|
289
315
|
|
290
|
-
|
291
|
-
|
292
|
-
} else {
|
293
|
-
unsubscribeFromNetworkRequest && unsubscribeFromNetworkRequest();
|
294
|
-
}
|
295
|
-
|
296
|
-
retainReference && retainReference.dispose();
|
297
|
-
cancelOnLoadCallback && cancelOnLoadCallback();
|
316
|
+
releaseQuery();
|
317
|
+
cancelNetworkRequest();
|
298
318
|
isDisposed = true;
|
299
319
|
},
|
320
|
+
releaseQuery: releaseQuery,
|
321
|
+
cancelNetworkRequest: cancelNetworkRequest,
|
300
322
|
fetchKey: fetchKey,
|
301
323
|
id: queryId,
|
302
324
|
|
303
325
|
// $FlowFixMe[unsafe-getters-setters] - this has no side effects
|
304
326
|
get isDisposed() {
|
305
|
-
return isDisposed;
|
327
|
+
return isDisposed || isReleased;
|
306
328
|
},
|
307
329
|
|
308
330
|
// $FlowFixMe[unsafe-getters-setters] - this has no side effects
|