1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | 'use strict';
|
12 |
|
13 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
14 |
|
15 | var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread"));
|
16 |
|
17 | var ProfilerContext = require('./ProfilerContext');
|
18 |
|
19 |
|
20 | var Scheduler = require('scheduler');
|
21 |
|
22 |
|
23 | var getRefetchMetadata = require('./getRefetchMetadata');
|
24 |
|
25 | var getValueAtPath = require('./getValueAtPath');
|
26 |
|
27 | var invariant = require("fbjs/lib/invariant");
|
28 |
|
29 | var useFetchTrackingRef = require('./useFetchTrackingRef');
|
30 |
|
31 | var useFragmentNode = require('./useFragmentNode');
|
32 |
|
33 | var useIsMountedRef = require('./useIsMountedRef');
|
34 |
|
35 | var useMemoVariables = require('./useMemoVariables');
|
36 |
|
37 | var useRelayEnvironment = require('./useRelayEnvironment');
|
38 |
|
39 | var warning = require("fbjs/lib/warning");
|
40 |
|
41 | var _require = require('./FragmentResource'),
|
42 | getFragmentResourceForEnvironment = _require.getFragmentResourceForEnvironment;
|
43 |
|
44 | var _require2 = require('./QueryResource'),
|
45 | getQueryResourceForEnvironment = _require2.getQueryResourceForEnvironment;
|
46 |
|
47 | var _require3 = require('react'),
|
48 | useCallback = _require3.useCallback,
|
49 | useContext = _require3.useContext,
|
50 | useEffect = _require3.useEffect,
|
51 | useMemo = _require3.useMemo,
|
52 | useReducer = _require3.useReducer,
|
53 | useRef = _require3.useRef;
|
54 |
|
55 | var _require4 = require('relay-runtime'),
|
56 | fetchQuery = _require4.__internal.fetchQuery,
|
57 | createOperationDescriptor = _require4.createOperationDescriptor,
|
58 | getFragmentIdentifier = _require4.getFragmentIdentifier,
|
59 | getSelector = _require4.getSelector;
|
60 |
|
61 | function reducer(state, action) {
|
62 | switch (action.type) {
|
63 | case 'refetch':
|
64 | {
|
65 | var _action$environment;
|
66 |
|
67 | return (0, _objectSpread2["default"])({}, state, {
|
68 | refetchVariables: action.refetchVariables,
|
69 | fetchPolicy: action.fetchPolicy,
|
70 | renderPolicy: action.renderPolicy,
|
71 | onComplete: action.onComplete,
|
72 | refetchEnvironment: action.environment,
|
73 | mirroredEnvironment: (_action$environment = action.environment) !== null && _action$environment !== void 0 ? _action$environment : state.mirroredEnvironment
|
74 | });
|
75 | }
|
76 |
|
77 | case 'reset':
|
78 | {
|
79 | return {
|
80 | fetchPolicy: undefined,
|
81 | renderPolicy: undefined,
|
82 | onComplete: undefined,
|
83 | refetchVariables: null,
|
84 | mirroredEnvironment: action.environment,
|
85 | mirroredFragmentIdentifier: action.fragmentIdentifier
|
86 | };
|
87 | }
|
88 |
|
89 | default:
|
90 | {
|
91 | action.type;
|
92 | throw new Error('useRefetchableFragmentNode: Unexpected action type');
|
93 | }
|
94 | }
|
95 | }
|
96 |
|
97 | function useRefetchableFragmentNode(fragmentNode, parentFragmentRef, componentDisplayName) {
|
98 | var _refetchEnvironment;
|
99 |
|
100 | var parentEnvironment = useRelayEnvironment();
|
101 |
|
102 | var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName),
|
103 | refetchableRequest = _getRefetchMetadata.refetchableRequest,
|
104 | fragmentRefPathInResponse = _getRefetchMetadata.fragmentRefPathInResponse;
|
105 |
|
106 | var fragmentIdentifier = getFragmentIdentifier(fragmentNode, parentFragmentRef);
|
107 |
|
108 | var _useReducer = useReducer(reducer, {
|
109 | fetchPolicy: undefined,
|
110 | renderPolicy: undefined,
|
111 | onComplete: undefined,
|
112 | refetchVariables: null,
|
113 | refetchEnvironment: null,
|
114 | mirroredEnvironment: parentEnvironment,
|
115 | mirroredFragmentIdentifier: fragmentIdentifier
|
116 | }),
|
117 | refetchState = _useReducer[0],
|
118 | dispatch = _useReducer[1];
|
119 |
|
120 | var _useFetchTrackingRef = useFetchTrackingRef(),
|
121 | startFetch = _useFetchTrackingRef.startFetch,
|
122 | disposeFetch = _useFetchTrackingRef.disposeFetch,
|
123 | completeFetch = _useFetchTrackingRef.completeFetch;
|
124 |
|
125 | var refetchGenerationRef = useRef(0);
|
126 | var refetchVariables = refetchState.refetchVariables,
|
127 | refetchEnvironment = refetchState.refetchEnvironment,
|
128 | fetchPolicy = refetchState.fetchPolicy,
|
129 | renderPolicy = refetchState.renderPolicy,
|
130 | onComplete = refetchState.onComplete,
|
131 | mirroredEnvironment = refetchState.mirroredEnvironment,
|
132 | mirroredFragmentIdentifier = refetchState.mirroredFragmentIdentifier;
|
133 | var environment = (_refetchEnvironment = refetchEnvironment) !== null && _refetchEnvironment !== void 0 ? _refetchEnvironment : parentEnvironment;
|
134 | var QueryResource = getQueryResourceForEnvironment(environment);
|
135 | var profilerContext = useContext(ProfilerContext);
|
136 | var shouldReset = environment !== mirroredEnvironment || fragmentIdentifier !== mirroredFragmentIdentifier;
|
137 |
|
138 | var _useMemoVariables = useMemoVariables(refetchVariables),
|
139 | memoRefetchVariables = _useMemoVariables[0];
|
140 |
|
141 | var refetchQuery = useMemo(function () {
|
142 | return memoRefetchVariables != null ? createOperationDescriptor(refetchableRequest, memoRefetchVariables) : null;
|
143 | }, [memoRefetchVariables, refetchableRequest]);
|
144 | var refetchedQueryResult;
|
145 | var fragmentRef = parentFragmentRef;
|
146 |
|
147 | if (shouldReset) {
|
148 | dispatch({
|
149 | type: 'reset',
|
150 | environment: environment,
|
151 | fragmentIdentifier: fragmentIdentifier
|
152 | });
|
153 | } else if (refetchQuery != null) {
|
154 | var _refetchGenerationRef;
|
155 |
|
156 |
|
157 | var debugPreviousIDAndTypename;
|
158 |
|
159 | if (process.env.NODE_ENV !== "production") {
|
160 | debugPreviousIDAndTypename = debugFunctions.getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, environment);
|
161 | }
|
162 |
|
163 |
|
164 |
|
165 |
|
166 | var _readQuery = readQuery(environment, refetchQuery, fetchPolicy, renderPolicy, (_refetchGenerationRef = refetchGenerationRef.current) !== null && _refetchGenerationRef !== void 0 ? _refetchGenerationRef : 0, componentDisplayName, {
|
167 | start: startFetch,
|
168 | complete: function complete(maybeError) {
|
169 | var _maybeError;
|
170 |
|
171 | completeFetch();
|
172 | onComplete && onComplete((_maybeError = maybeError) !== null && _maybeError !== void 0 ? _maybeError : null);
|
173 |
|
174 | if (process.env.NODE_ENV !== "production") {
|
175 | if (!maybeError) {
|
176 | debugFunctions.checkSameTypeAfterRefetch(debugPreviousIDAndTypename, environment, fragmentNode, componentDisplayName);
|
177 | }
|
178 | }
|
179 | }
|
180 | }, profilerContext),
|
181 | queryResult = _readQuery[0],
|
182 | queryData = _readQuery[1];
|
183 |
|
184 | refetchedQueryResult = queryResult;
|
185 |
|
186 |
|
187 |
|
188 |
|
189 | var refetchedFragmentRef = getValueAtPath(queryData, fragmentRefPathInResponse);
|
190 | fragmentRef = refetchedFragmentRef;
|
191 |
|
192 | if (process.env.NODE_ENV !== "production") {
|
193 | debugFunctions.checkSameIDAfterRefetch(debugPreviousIDAndTypename, fragmentRef, fragmentNode, componentDisplayName);
|
194 | }
|
195 | }
|
196 |
|
197 |
|
198 |
|
199 |
|
200 |
|
201 | var _useFragmentNode = useFragmentNode(fragmentNode, fragmentRef, componentDisplayName),
|
202 | fragmentData = _useFragmentNode.data,
|
203 | disableStoreUpdates = _useFragmentNode.disableStoreUpdates,
|
204 | enableStoreUpdates = _useFragmentNode.enableStoreUpdates;
|
205 |
|
206 | useEffect(function () {
|
207 |
|
208 |
|
209 | var queryDisposable = refetchedQueryResult != null ? QueryResource.retain(refetchedQueryResult) : null;
|
210 | return function () {
|
211 | if (queryDisposable) {
|
212 | queryDisposable.dispose();
|
213 | }
|
214 | };
|
215 |
|
216 |
|
217 |
|
218 | }, [QueryResource, fragmentIdentifier, refetchQuery]);
|
219 | var refetch = useRefetchFunction(fragmentNode, parentFragmentRef, fragmentIdentifier, fragmentRefPathInResponse, fragmentData, refetchGenerationRef, dispatch, disposeFetch, componentDisplayName);
|
220 | return {
|
221 | fragmentData: fragmentData,
|
222 | fragmentRef: fragmentRef,
|
223 | refetch: refetch,
|
224 | disableStoreUpdates: disableStoreUpdates,
|
225 | enableStoreUpdates: enableStoreUpdates
|
226 | };
|
227 | }
|
228 |
|
229 | function useRefetchFunction(fragmentNode, parentFragmentRef, fragmentIdentifier, fragmentRefPathInResponse, fragmentData, refetchGenerationRef, dispatch, disposeFetch, componentDisplayName) {
|
230 | var isMountedRef = useIsMountedRef();
|
231 |
|
232 | var dataID = fragmentData === null || fragmentData === void 0 ? void 0 : fragmentData.id;
|
233 | return useCallback(function (providedRefetchVariables, options) {
|
234 | var _refetchGenerationRef2;
|
235 |
|
236 |
|
237 |
|
238 | if (isMountedRef.current !== true) {
|
239 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` on unmounted component for fragment ' + '`%s` in `%s`. It looks like some instances of your component are ' + 'still trying to fetch data but they already unmounted. ' + 'Please make sure you clear all timers, intervals, ' + 'async calls, etc that may trigger a fetch.', fragmentNode.name, componentDisplayName) : void 0;
|
240 | return {
|
241 | dispose: function dispose() {}
|
242 | };
|
243 | }
|
244 |
|
245 | if (Scheduler.unstable_getCurrentPriorityLevel() < Scheduler.unstable_NormalPriority) {
|
246 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` at a priority higher than ' + 'expected on fragment `%s` in `%s`. It looks like you tried to ' + 'call `refetch` under a high priority update, but updates that ' + 'can cause the component to suspend should be scheduled at ' + 'normal priority. Make sure you are calling `refetch` inside ' + '`startTransition()` from the `useSuspenseTransition()` hook.', fragmentNode.name, componentDisplayName) : void 0;
|
247 | }
|
248 |
|
249 | if (parentFragmentRef == null) {
|
250 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected call to `refetch` while using a null fragment ref ' + 'for fragment `%s` in `%s`. When calling `refetch`, we expect ' + "initial fragment data to be non-null. Please make sure you're " + 'passing a valid fragment ref to `%s` before calling ' + '`refetch`, or make sure you pass all required variables to `refetch`.', fragmentNode.name, componentDisplayName, componentDisplayName) : void 0;
|
251 | }
|
252 |
|
253 | refetchGenerationRef.current = ((_refetchGenerationRef2 = refetchGenerationRef.current) !== null && _refetchGenerationRef2 !== void 0 ? _refetchGenerationRef2 : 0) + 1;
|
254 | var environment = options === null || options === void 0 ? void 0 : options.__environment;
|
255 | var fetchPolicy = options === null || options === void 0 ? void 0 : options.fetchPolicy;
|
256 | var renderPolicy = options === null || options === void 0 ? void 0 : options.renderPolicy_UNSTABLE;
|
257 | var onComplete = options === null || options === void 0 ? void 0 : options.onComplete;
|
258 | var fragmentSelector = getSelector(fragmentNode, parentFragmentRef);
|
259 | var parentVariables;
|
260 | var fragmentVariables;
|
261 |
|
262 | if (fragmentSelector == null) {
|
263 | parentVariables = {};
|
264 | fragmentVariables = {};
|
265 | } else if (fragmentSelector.kind === 'PluralReaderSelector') {
|
266 | var _ref, _fragmentSelector$sel, _ref2, _fragmentSelector$sel2;
|
267 |
|
268 | parentVariables = (_ref = (_fragmentSelector$sel = fragmentSelector.selectors[0]) === null || _fragmentSelector$sel === void 0 ? void 0 : _fragmentSelector$sel.owner.variables) !== null && _ref !== void 0 ? _ref : {};
|
269 | fragmentVariables = (_ref2 = (_fragmentSelector$sel2 = fragmentSelector.selectors[0]) === null || _fragmentSelector$sel2 === void 0 ? void 0 : _fragmentSelector$sel2.variables) !== null && _ref2 !== void 0 ? _ref2 : {};
|
270 | } else {
|
271 | parentVariables = fragmentSelector.owner.variables;
|
272 | fragmentVariables = fragmentSelector.variables;
|
273 | }
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 | var refetchVariables = (0, _objectSpread2["default"])({}, parentVariables, fragmentVariables, providedRefetchVariables);
|
280 |
|
281 |
|
282 | if (fragmentRefPathInResponse.includes('node') && !providedRefetchVariables.hasOwnProperty('id')) {
|
283 |
|
284 |
|
285 |
|
286 | if (typeof dataID !== 'string') {
|
287 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`id` in order to refetch, got `%s`.', dataID) : void 0;
|
288 | }
|
289 |
|
290 | refetchVariables.id = dataID;
|
291 | }
|
292 |
|
293 | dispatch({
|
294 | type: 'refetch',
|
295 | refetchVariables: refetchVariables,
|
296 | fetchPolicy: fetchPolicy,
|
297 | renderPolicy: renderPolicy,
|
298 | onComplete: onComplete,
|
299 | environment: environment
|
300 | });
|
301 | return {
|
302 | dispose: disposeFetch
|
303 | };
|
304 | },
|
305 |
|
306 |
|
307 |
|
308 |
|
309 |
|
310 |
|
311 | [fragmentIdentifier, dataID, dispatch, disposeFetch]);
|
312 | }
|
313 |
|
314 | function readQuery(environment, query, fetchPolicy, renderPolicy, refetchGeneration, componentDisplayName, _ref3, profilerContext) {
|
315 | var start = _ref3.start,
|
316 | complete = _ref3.complete;
|
317 | var QueryResource = getQueryResourceForEnvironment(environment);
|
318 | var FragmentResource = getFragmentResourceForEnvironment(environment);
|
319 | var queryResult = profilerContext.wrapPrepareQueryResource(function () {
|
320 | return QueryResource.prepare(query, fetchQuery(environment, query, {
|
321 | networkCacheConfig: {
|
322 | force: true
|
323 | }
|
324 | }), fetchPolicy, renderPolicy, {
|
325 | start: start,
|
326 | error: complete,
|
327 | complete: complete
|
328 | },
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 |
|
336 | refetchGeneration);
|
337 | });
|
338 | var queryData = FragmentResource.read(queryResult.fragmentNode, queryResult.fragmentRef, componentDisplayName).data;
|
339 | !(queryData != null) ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to be able to read refetch query response. ' + "If you're seeing this, this is likely a bug in Relay.") : invariant(false) : void 0;
|
340 | return [queryResult, queryData];
|
341 | }
|
342 |
|
343 | var debugFunctions;
|
344 |
|
345 | if (process.env.NODE_ENV !== "production") {
|
346 | debugFunctions = {
|
347 | getInitialIDAndType: function getInitialIDAndType(memoRefetchVariables, fragmentRefPathInResponse, environment) {
|
348 | var _require5 = require('relay-runtime'),
|
349 | Record = _require5.Record;
|
350 |
|
351 | var id = memoRefetchVariables === null || memoRefetchVariables === void 0 ? void 0 : memoRefetchVariables.id;
|
352 |
|
353 | if (fragmentRefPathInResponse.length !== 1 || fragmentRefPathInResponse[0] !== 'node' || id == null) {
|
354 | return null;
|
355 | }
|
356 |
|
357 | var recordSource = environment.getStore().getSource();
|
358 | var record = recordSource.get(id);
|
359 | var typename = record && Record.getType(record);
|
360 |
|
361 | if (typename == null) {
|
362 | return null;
|
363 | }
|
364 |
|
365 | return {
|
366 | id: id,
|
367 | typename: typename
|
368 | };
|
369 | },
|
370 | checkSameTypeAfterRefetch: function checkSameTypeAfterRefetch(previousIDAndType, environment, fragmentNode, componentDisplayName) {
|
371 | var _require6 = require('relay-runtime'),
|
372 | Record = _require6.Record;
|
373 |
|
374 | if (!previousIDAndType) {
|
375 | return;
|
376 | }
|
377 |
|
378 | var recordSource = environment.getStore().getSource();
|
379 | var record = recordSource.get(previousIDAndType.id);
|
380 | var typename = record && Record.getType(record);
|
381 |
|
382 | if (typename !== previousIDAndType.typename) {
|
383 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Call to `refetch` returned data with a different ' + '__typename: was `%s`, now `%s`, on `%s` in `%s`. ' + 'Please make sure the server correctly implements' + 'unique id requirement.', previousIDAndType.typename, typename, fragmentNode.name, componentDisplayName) : void 0;
|
384 | }
|
385 | },
|
386 | checkSameIDAfterRefetch: function checkSameIDAfterRefetch(previousIDAndTypename, refetchedFragmentRef, fragmentNode, componentDisplayName) {
|
387 | if (previousIDAndTypename == null) {
|
388 | return;
|
389 | }
|
390 |
|
391 | var _require7 = require('relay-runtime'),
|
392 | ID_KEY = _require7.ID_KEY;
|
393 |
|
394 |
|
395 | var resultID = refetchedFragmentRef[ID_KEY];
|
396 |
|
397 | if (resultID != null && resultID !== previousIDAndTypename.id) {
|
398 | process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Call to `refetch` returned a different id, expected ' + '`%s`, got `%s`, on `%s` in `%s`. ' + 'Please make sure the server correctly implements ' + 'unique id requirement.', resultID, previousIDAndTypename.id, fragmentNode.name, componentDisplayName) : void 0;
|
399 | }
|
400 | }
|
401 | };
|
402 | }
|
403 |
|
404 | module.exports = useRefetchableFragmentNode; |
\ | No newline at end of file |