relay-runtime 18.2.0 → 19.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.
- package/experimental.js +1 -1
- package/experimental.js.flow +8 -6
- package/index.js +1 -1
- package/index.js.flow +3 -0
- package/lib/experimental.js +5 -2
- package/lib/index.js +3 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +1 -1
- package/lib/mutations/RelayRecordSourceProxy.js +2 -1
- package/lib/mutations/createUpdatableProxy.js +1 -1
- package/lib/mutations/validateMutation.js +2 -2
- package/lib/network/RelayObservable.js +1 -3
- package/lib/network/wrapNetworkWithLogObserver.js +2 -2
- package/lib/query/fetchQuery.js +1 -1
- package/lib/store/DataChecker.js +4 -5
- package/lib/store/OperationExecutor.js +11 -0
- package/lib/store/RelayModernEnvironment.js +13 -4
- package/lib/store/RelayModernFragmentSpecResolver.js +4 -4
- package/lib/store/RelayModernStore.js +43 -21
- package/lib/store/RelayPublishQueue.js +11 -15
- package/lib/store/RelayReader.js +131 -151
- package/lib/store/RelayReferenceMarker.js +3 -4
- package/lib/store/RelayResponseNormalizer.js +47 -26
- package/lib/store/RelayStoreSubscriptions.js +2 -2
- package/lib/store/RelayStoreUtils.js +8 -0
- package/lib/store/ResolverFragments.js +2 -2
- package/lib/store/createRelayLoggingContext.js +17 -0
- package/lib/store/generateTypenamePrefixedDataID.js +9 -0
- package/lib/store/live-resolvers/LiveResolverCache.js +2 -1
- package/lib/store/live-resolvers/resolverDataInjector.js +4 -4
- package/lib/store/observeFragmentExperimental.js +60 -13
- package/lib/store/observeQueryExperimental.js +21 -0
- package/lib/util/RelayFeatureFlags.js +6 -1
- package/lib/util/handlePotentialSnapshotErrors.js +11 -8
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +1 -0
- package/mutations/RelayRecordSourceProxy.js.flow +4 -0
- package/mutations/createUpdatableProxy.js.flow +1 -1
- package/mutations/validateMutation.js.flow +3 -3
- package/network/RelayNetworkTypes.js.flow +3 -0
- package/network/RelayObservable.js.flow +1 -5
- package/network/wrapNetworkWithLogObserver.js.flow +19 -1
- package/package.json +1 -1
- package/query/fetchQuery.js.flow +1 -1
- package/store/DataChecker.js.flow +5 -2
- package/store/OperationExecutor.js.flow +12 -1
- package/store/RelayExperimentalGraphResponseTransform.js.flow +4 -4
- package/store/RelayModernEnvironment.js.flow +22 -6
- package/store/RelayModernFragmentSpecResolver.js.flow +6 -6
- package/store/RelayModernSelector.js.flow +2 -0
- package/store/RelayModernStore.js.flow +74 -27
- package/store/RelayPublishQueue.js.flow +32 -21
- package/store/RelayReader.js.flow +159 -96
- package/store/RelayReferenceMarker.js.flow +3 -4
- package/store/RelayResponseNormalizer.js.flow +93 -67
- package/store/RelayStoreSubscriptions.js.flow +2 -2
- package/store/RelayStoreTypes.js.flow +33 -4
- package/store/RelayStoreUtils.js.flow +29 -0
- package/store/ResolverCache.js.flow +2 -2
- package/store/ResolverFragments.js.flow +5 -3
- package/store/StoreInspector.js.flow +5 -0
- package/store/createRelayContext.js.flow +3 -2
- package/store/createRelayLoggingContext.js.flow +46 -0
- package/store/generateTypenamePrefixedDataID.js.flow +25 -0
- package/store/live-resolvers/LiveResolverCache.js.flow +2 -1
- package/store/live-resolvers/resolverDataInjector.js.flow +10 -6
- package/store/observeFragmentExperimental.js.flow +82 -28
- package/store/observeQueryExperimental.js.flow +61 -0
- package/store/waitForFragmentExperimental.js.flow +4 -3
- package/util/NormalizationNode.js.flow +2 -1
- package/util/RelayConcreteNode.js.flow +2 -0
- package/util/RelayError.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +18 -0
- package/util/RelayRuntimeTypes.js.flow +6 -3
- package/util/getPaginationVariables.js.flow +2 -0
- package/util/handlePotentialSnapshotErrors.js.flow +23 -11
- package/util/registerEnvironmentWithDevTools.js.flow +4 -2
- package/util/withProvidedVariables.js.flow +1 -0
- package/util/withStartAndDuration.js.flow +3 -0
- package/relay-runtime-experimental.js +0 -4
- package/relay-runtime-experimental.min.js +0 -9
- package/relay-runtime.js +0 -4
- package/relay-runtime.min.js +0 -9
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
import type {Fragment} from '../../util/RelayRuntimeTypes';
|
|
15
|
-
import type {FragmentType} from '../RelayStoreTypes';
|
|
15
|
+
import type {FragmentType, ResolverContext} from '../RelayStoreTypes';
|
|
16
16
|
|
|
17
17
|
const {readFragment} = require('../ResolverFragments');
|
|
18
18
|
const invariant = require('invariant');
|
|
19
19
|
|
|
20
|
-
type ResolverFn = ($FlowFixMe, ?$FlowFixMe) => mixed;
|
|
20
|
+
type ResolverFn = ($FlowFixMe, ?$FlowFixMe, ResolverContext) => mixed;
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
*
|
|
@@ -40,7 +40,11 @@ function resolverDataInjector<TFragmentType: FragmentType, TData: ?{...}>(
|
|
|
40
40
|
isRequiredField?: boolean,
|
|
41
41
|
): (fragmentKey: TFragmentType, args: mixed) => mixed {
|
|
42
42
|
const resolverFn: ResolverFn = _resolverFn;
|
|
43
|
-
return (
|
|
43
|
+
return (
|
|
44
|
+
fragmentKey: TFragmentType,
|
|
45
|
+
args: mixed,
|
|
46
|
+
resolverContext: ResolverContext,
|
|
47
|
+
): mixed => {
|
|
44
48
|
const data = readFragment(fragment, fragmentKey);
|
|
45
49
|
if (fieldName != null) {
|
|
46
50
|
if (data == null) {
|
|
@@ -52,7 +56,7 @@ function resolverDataInjector<TFragmentType: FragmentType, TData: ?{...}>(
|
|
|
52
56
|
fragment.name,
|
|
53
57
|
);
|
|
54
58
|
} else {
|
|
55
|
-
return resolverFn(null, args);
|
|
59
|
+
return resolverFn(null, args, resolverContext); // TODO: This statement does not seem to be covered by a test?
|
|
56
60
|
}
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -70,7 +74,7 @@ function resolverDataInjector<TFragmentType: FragmentType, TData: ?{...}>(
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
// $FlowFixMe[invalid-computed-prop]
|
|
73
|
-
return resolverFn(data[fieldName], args);
|
|
77
|
+
return resolverFn(data[fieldName], args, resolverContext);
|
|
74
78
|
} else {
|
|
75
79
|
// If both `data` and `fieldName` is available, we expect the
|
|
76
80
|
// `fieldName` field in the `data` object.
|
|
@@ -83,7 +87,7 @@ function resolverDataInjector<TFragmentType: FragmentType, TData: ?{...}>(
|
|
|
83
87
|
}
|
|
84
88
|
} else {
|
|
85
89
|
// By default we will pass the full set of the fragment data to the resolver
|
|
86
|
-
return resolverFn(
|
|
90
|
+
return resolverFn(null, args, resolverContext); // TODO: This statement does not seem to be covered by a test?
|
|
87
91
|
}
|
|
88
92
|
};
|
|
89
93
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @oncall relay
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import type {RequestDescriptor} from './RelayStoreTypes';
|
|
12
|
+
import type {PluralReaderSelector, RequestDescriptor} from './RelayStoreTypes';
|
|
13
13
|
import type {
|
|
14
14
|
Fragment,
|
|
15
15
|
FragmentType,
|
|
@@ -20,8 +20,8 @@ import type {
|
|
|
20
20
|
} from 'relay-runtime';
|
|
21
21
|
|
|
22
22
|
const Observable = require('../network/RelayObservable');
|
|
23
|
+
const {getObservableForActiveRequest} = require('../query/fetchQueryInternal');
|
|
23
24
|
const {getFragment} = require('../query/GraphQLTag');
|
|
24
|
-
const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
|
|
25
25
|
const {
|
|
26
26
|
handlePotentialSnapshotErrors,
|
|
27
27
|
} = require('../util/handlePotentialSnapshotErrors');
|
|
@@ -47,8 +47,7 @@ export type HasSpread<TFragmentType> = {
|
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* EXPERIMENTAL: This API is experimental and does not yet support all Relay
|
|
50
|
-
* features. Notably, it does not
|
|
51
|
-
* features of Relay Resolvers.
|
|
50
|
+
* features. Notably, it does not correctly handle some features of Relay Resolvers.
|
|
52
51
|
*
|
|
53
52
|
* Given a fragment and a fragment reference, returns a promise that resolves
|
|
54
53
|
* once the fragment data is available, or rejects if the fragment has an error.
|
|
@@ -63,7 +62,9 @@ export type HasSpread<TFragmentType> = {
|
|
|
63
62
|
async function waitForFragmentData<TFragmentType: FragmentType, TData>(
|
|
64
63
|
environment: IEnvironment,
|
|
65
64
|
fragment: Fragment<TFragmentType, TData>,
|
|
66
|
-
fragmentRef:
|
|
65
|
+
fragmentRef:
|
|
66
|
+
| HasSpread<TFragmentType>
|
|
67
|
+
| $ReadOnlyArray<HasSpread<TFragmentType>>,
|
|
67
68
|
): Promise<TData> {
|
|
68
69
|
let subscription: ?Subscription;
|
|
69
70
|
|
|
@@ -94,13 +95,14 @@ async function waitForFragmentData<TFragmentType: FragmentType, TData>(
|
|
|
94
95
|
declare function observeFragment<TFragmentType: FragmentType, TData>(
|
|
95
96
|
environment: IEnvironment,
|
|
96
97
|
fragment: Fragment<TFragmentType, TData>,
|
|
97
|
-
fragmentRef:
|
|
98
|
+
fragmentRef:
|
|
99
|
+
| HasSpread<TFragmentType>
|
|
100
|
+
| $ReadOnlyArray<HasSpread<TFragmentType>>,
|
|
98
101
|
): Observable<FragmentState<TData>>;
|
|
99
102
|
|
|
100
103
|
/**
|
|
101
104
|
* EXPERIMENTAL: This API is experimental and does not yet support all Relay
|
|
102
|
-
* features. Notably, it does not
|
|
103
|
-
* features of Relay Resolvers.
|
|
105
|
+
* features. Notably, it does not correctly handle some features of Relay Resolvers.
|
|
104
106
|
*
|
|
105
107
|
* Given a fragment and a fragment reference, returns an observable that emits
|
|
106
108
|
* the state of the fragment over time. The observable will emit the following
|
|
@@ -114,7 +116,7 @@ function observeFragment<TFragmentType: FragmentType, TData>(
|
|
|
114
116
|
environment: IEnvironment,
|
|
115
117
|
fragment: Fragment<TFragmentType, TData>,
|
|
116
118
|
fragmentRef: mixed,
|
|
117
|
-
):
|
|
119
|
+
): mixed {
|
|
118
120
|
const fragmentNode = getFragment(fragment);
|
|
119
121
|
const fragmentSelector = getSelector(fragmentNode, fragmentRef);
|
|
120
122
|
invariant(
|
|
@@ -124,24 +126,19 @@ function observeFragment<TFragmentType: FragmentType, TData>(
|
|
|
124
126
|
invariant(fragmentSelector != null, 'Expected a selector, got null.');
|
|
125
127
|
switch (fragmentSelector.kind) {
|
|
126
128
|
case 'SingularReaderSelector':
|
|
127
|
-
return
|
|
129
|
+
return observeSingularSelector(environment, fragment, fragmentSelector);
|
|
128
130
|
case 'PluralReaderSelector': {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// lets you subscribe at a singular fragment granularity. This makes it
|
|
135
|
-
// hard to batch updates such that when a store update causes multiple
|
|
136
|
-
// fragments to change, we can only publish a single update to the
|
|
137
|
-
// fragment owner.
|
|
138
|
-
invariant(false, 'Plural fragments are not supported');
|
|
131
|
+
return observePluralSelector(
|
|
132
|
+
environment,
|
|
133
|
+
(fragment: $FlowFixMe),
|
|
134
|
+
fragmentSelector,
|
|
135
|
+
);
|
|
139
136
|
}
|
|
140
137
|
}
|
|
141
138
|
invariant(false, 'Unsupported fragment selector kind');
|
|
142
139
|
}
|
|
143
140
|
|
|
144
|
-
function
|
|
141
|
+
function observeSingularSelector<TFragmentType: FragmentType, TData>(
|
|
145
142
|
environment: IEnvironment,
|
|
146
143
|
fragmentNode: Fragment<TFragmentType, TData>,
|
|
147
144
|
fragmentSelector: SingularReaderSelector,
|
|
@@ -173,6 +170,49 @@ function observeSelector<TFragmentType: FragmentType, TData>(
|
|
|
173
170
|
});
|
|
174
171
|
}
|
|
175
172
|
|
|
173
|
+
function observePluralSelector<
|
|
174
|
+
TFragmentType: FragmentType,
|
|
175
|
+
TData: Array<mixed>,
|
|
176
|
+
>(
|
|
177
|
+
environment: IEnvironment,
|
|
178
|
+
fragmentNode: Fragment<TFragmentType, TData>,
|
|
179
|
+
fragmentSelector: PluralReaderSelector,
|
|
180
|
+
): Observable<FragmentState<TData>> {
|
|
181
|
+
const snapshots = fragmentSelector.selectors.map(selector =>
|
|
182
|
+
environment.lookup(selector),
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
return Observable.create(sink => {
|
|
186
|
+
// This array is mutable since each subscription updates the array in place.
|
|
187
|
+
const states = snapshots.map((snapshot, index) =>
|
|
188
|
+
snapshotToFragmentState(
|
|
189
|
+
environment,
|
|
190
|
+
fragmentNode,
|
|
191
|
+
fragmentSelector.selectors[index].owner,
|
|
192
|
+
snapshot,
|
|
193
|
+
),
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
sink.next((mergeFragmentStates(states): $FlowFixMe));
|
|
197
|
+
|
|
198
|
+
const subscriptions = snapshots.map((snapshot, index) =>
|
|
199
|
+
environment.subscribe(snapshot, latestSnapshot => {
|
|
200
|
+
states[index] = snapshotToFragmentState(
|
|
201
|
+
environment,
|
|
202
|
+
fragmentNode,
|
|
203
|
+
fragmentSelector.selectors[index].owner,
|
|
204
|
+
latestSnapshot,
|
|
205
|
+
);
|
|
206
|
+
// This doesn't batch updates, so it will notify the subscriber multiple times
|
|
207
|
+
// if a store update impacting multiple items in the list is published.
|
|
208
|
+
sink.next((mergeFragmentStates(states): $FlowFixMe));
|
|
209
|
+
}),
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
return () => subscriptions.forEach(subscription => subscription.dispose());
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
176
216
|
function snapshotToFragmentState<TFragmentType: FragmentType, TData>(
|
|
177
217
|
environment: IEnvironment,
|
|
178
218
|
fragmentNode: Fragment<TFragmentType, TData>,
|
|
@@ -201,18 +241,18 @@ function snapshotToFragmentState<TFragmentType: FragmentType, TData>(
|
|
|
201
241
|
}
|
|
202
242
|
|
|
203
243
|
if (snapshot.isMissingData) {
|
|
204
|
-
|
|
205
|
-
environment,
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
244
|
+
if (
|
|
245
|
+
getObservableForActiveRequest(environment, owner) != null ||
|
|
246
|
+
environment
|
|
247
|
+
.getOperationTracker()
|
|
248
|
+
.getPendingOperationsAffectingOwner(owner) != null
|
|
249
|
+
) {
|
|
210
250
|
return {state: 'loading'};
|
|
211
251
|
}
|
|
212
252
|
}
|
|
213
253
|
|
|
214
254
|
try {
|
|
215
|
-
handlePotentialSnapshotErrors(environment, snapshot.
|
|
255
|
+
handlePotentialSnapshotErrors(environment, snapshot.fieldErrors);
|
|
216
256
|
} catch (error) {
|
|
217
257
|
return {error, state: 'error'};
|
|
218
258
|
}
|
|
@@ -229,6 +269,20 @@ function snapshotToFragmentState<TFragmentType: FragmentType, TData>(
|
|
|
229
269
|
return {state: 'ok', value: (snapshot.data: $FlowFixMe)};
|
|
230
270
|
}
|
|
231
271
|
|
|
272
|
+
function mergeFragmentStates<T>(
|
|
273
|
+
states: $ReadOnlyArray<FragmentState<T>>,
|
|
274
|
+
): FragmentState<Array<T>> {
|
|
275
|
+
const value = [];
|
|
276
|
+
for (const state of states) {
|
|
277
|
+
if (state.state === 'ok') {
|
|
278
|
+
value.push(state.value);
|
|
279
|
+
} else {
|
|
280
|
+
return state;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
return {state: 'ok', value};
|
|
284
|
+
}
|
|
285
|
+
|
|
232
286
|
module.exports = {
|
|
233
287
|
observeFragment,
|
|
234
288
|
waitForFragmentData,
|
|
@@ -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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
* @oncall relay
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
import type RelayObservable from '../network/RelayObservable';
|
|
15
|
+
import type {FragmentState} from './observeFragmentExperimental';
|
|
16
|
+
import type {OperationDescriptor} from './RelayStoreTypes';
|
|
17
|
+
import type {Fragment, IEnvironment, Query, Variables} from 'relay-runtime';
|
|
18
|
+
|
|
19
|
+
const {observeFragment} = require('./observeFragmentExperimental');
|
|
20
|
+
const {createOperationDescriptor} = require('./RelayModernOperationDescriptor');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* This function returns an observable that can be used to subscribe to the data
|
|
24
|
+
* contained in a query. It does not return the full response shape, but rather
|
|
25
|
+
* the contents of the query body minus any fragment spreads. If you wish to
|
|
26
|
+
* read the contents of a fragment spread into this query you may pass the
|
|
27
|
+
* object into which the fragment was spread to `observeFragment`.
|
|
28
|
+
*
|
|
29
|
+
* NOTE: `observeQuery` assumes that you have already fetched and retained the
|
|
30
|
+
* query via some other means, such as `fetchQuery`.
|
|
31
|
+
*
|
|
32
|
+
* This feature is still experimental and does not properly handle some resolver
|
|
33
|
+
* features such as client-to-server edges.
|
|
34
|
+
*/
|
|
35
|
+
function observeQuery<TVariables: Variables, TData>(
|
|
36
|
+
environment: IEnvironment,
|
|
37
|
+
gqlQuery: Query<TVariables, TData>,
|
|
38
|
+
variables: TVariables,
|
|
39
|
+
): RelayObservable<FragmentState<TData>> {
|
|
40
|
+
const operation: OperationDescriptor = createOperationDescriptor(
|
|
41
|
+
gqlQuery,
|
|
42
|
+
variables,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const rootFragmentRef: $FlowFixMe = {
|
|
46
|
+
__id: operation.fragment.dataID,
|
|
47
|
+
__fragments: {
|
|
48
|
+
[operation.fragment.node.name]: operation.request.variables,
|
|
49
|
+
},
|
|
50
|
+
__fragmentOwner: operation.request,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const fragmentNode: Fragment<$FlowFixMe, TData> = (operation.request.node
|
|
54
|
+
.fragment: $FlowFixMe);
|
|
55
|
+
|
|
56
|
+
return observeFragment(environment, fragmentNode, rootFragmentRef);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = {
|
|
60
|
+
observeQuery,
|
|
61
|
+
};
|
|
@@ -21,8 +21,7 @@ const {observeFragment} = require('./observeFragmentExperimental');
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* EXPERIMENTAL: This API is experimental and does not yet support all Relay
|
|
24
|
-
* features. Notably, it does not
|
|
25
|
-
* features of Relay Resolvers.
|
|
24
|
+
* features. Notably, it does not correctly handle some features of Relay Resolvers.
|
|
26
25
|
*
|
|
27
26
|
* Given a fragment and a fragment reference, returns a promise that resolves
|
|
28
27
|
* once the fragment data is available, or rejects if the fragment has an error.
|
|
@@ -37,7 +36,9 @@ const {observeFragment} = require('./observeFragmentExperimental');
|
|
|
37
36
|
async function waitForFragmentData<TFragmentType: FragmentType, TData>(
|
|
38
37
|
environment: IEnvironment,
|
|
39
38
|
fragment: Fragment<TFragmentType, TData>,
|
|
40
|
-
fragmentRef:
|
|
39
|
+
fragmentRef:
|
|
40
|
+
| HasSpread<TFragmentType>
|
|
41
|
+
| $ReadOnlyArray<HasSpread<TFragmentType>>,
|
|
41
42
|
): Promise<TData> {
|
|
42
43
|
let subscription: ?Subscription;
|
|
43
44
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
import type {ResolverFunction, ResolverModule} from './ReaderNode';
|
|
15
|
-
import type {ConcreteRequest} from './RelayConcreteNode';
|
|
15
|
+
import type {ConcreteRequest, ProvidedVariableType} from './RelayConcreteNode';
|
|
16
16
|
import type {JSResourceReference} from 'JSResourceReference';
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -28,6 +28,7 @@ export type NormalizationOperation = {
|
|
|
28
28
|
+[string]: $ReadOnlyArray<string>,
|
|
29
29
|
},
|
|
30
30
|
+use_exec_time_resolvers?: boolean,
|
|
31
|
+
+exec_time_resolvers_enabled_provider?: ProvidedVariableType,
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
export type NormalizationHandle =
|
package/util/RelayError.js.flow
CHANGED
|
@@ -26,6 +26,7 @@ export type FeatureFlags = {
|
|
|
26
26
|
STRING_INTERN_LEVEL: number,
|
|
27
27
|
LOG_MISSING_RECORDS_IN_PROD: boolean,
|
|
28
28
|
ENABLE_RELAY_OPERATION_TRACKER_SUSPENSE: boolean,
|
|
29
|
+
ENABLE_UI_CONTEXT_ON_RELAY_LOGGER: boolean,
|
|
29
30
|
|
|
30
31
|
// Some GraphQL servers are noncompliant with the GraphQL specification and
|
|
31
32
|
// return an empty list instead of null when there is a field error on a list.
|
|
@@ -58,6 +59,18 @@ export type FeatureFlags = {
|
|
|
58
59
|
// Adds a prefix to the storage key of read time resolvers. This is used to
|
|
59
60
|
// disambiguate the same resolver being used at both read time and exec time.
|
|
60
61
|
ENABLE_READ_TIME_RESOLVER_STORAGE_KEY_PREFIX: boolean,
|
|
62
|
+
|
|
63
|
+
// Enable the fix for usePaginationFragment stucking in loading state
|
|
64
|
+
ENABLE_USE_PAGINATION_IS_LOADING_FIX: boolean,
|
|
65
|
+
|
|
66
|
+
// Enable logging an ID collision in the Relay store
|
|
67
|
+
ENABLE_STORE_ID_COLLISION_LOGGING: boolean,
|
|
68
|
+
|
|
69
|
+
// Throw on nested store updates
|
|
70
|
+
DISALLOW_NESTED_UPDATES: boolean,
|
|
71
|
+
|
|
72
|
+
// Enable prefixing of DataID in the store with __typename
|
|
73
|
+
ENABLE_TYPENAME_PREFIXED_DATA_ID: boolean,
|
|
61
74
|
};
|
|
62
75
|
|
|
63
76
|
const RelayFeatureFlags: FeatureFlags = {
|
|
@@ -72,6 +85,7 @@ const RelayFeatureFlags: FeatureFlags = {
|
|
|
72
85
|
MAX_DATA_ID_LENGTH: null,
|
|
73
86
|
STRING_INTERN_LEVEL: 0,
|
|
74
87
|
LOG_MISSING_RECORDS_IN_PROD: false,
|
|
88
|
+
ENABLE_STORE_ID_COLLISION_LOGGING: false,
|
|
75
89
|
ENABLE_NONCOMPLIANT_ERROR_HANDLING_ON_LISTS: false,
|
|
76
90
|
ENABLE_LOOSE_SUBSCRIPTION_ATTRIBUTION: false,
|
|
77
91
|
ENABLE_OPERATION_TRACKER_OPTIMISTIC_UPDATES: false,
|
|
@@ -81,6 +95,10 @@ const RelayFeatureFlags: FeatureFlags = {
|
|
|
81
95
|
ENABLE_CYLE_DETECTION_IN_VARIABLES: false,
|
|
82
96
|
ENABLE_ACTIVITY_COMPATIBILITY: false,
|
|
83
97
|
ENABLE_READ_TIME_RESOLVER_STORAGE_KEY_PREFIX: true,
|
|
98
|
+
ENABLE_USE_PAGINATION_IS_LOADING_FIX: false,
|
|
99
|
+
DISALLOW_NESTED_UPDATES: false,
|
|
100
|
+
ENABLE_TYPENAME_PREFIXED_DATA_ID: false,
|
|
101
|
+
ENABLE_UI_CONTEXT_ON_RELAY_LOGGER: false,
|
|
84
102
|
};
|
|
85
103
|
|
|
86
104
|
module.exports = RelayFeatureFlags;
|
|
@@ -53,9 +53,10 @@ export type VariablesOf<T: OperationType> = T['variables'];
|
|
|
53
53
|
* state of any configured response cache.
|
|
54
54
|
* - `poll`: causes a query to live update by polling at the specified interval
|
|
55
55
|
* in milliseconds. (This value will be passed to setTimeout.)
|
|
56
|
-
* - `liveConfigId`:
|
|
57
|
-
*
|
|
58
|
-
* - `
|
|
56
|
+
* - `liveConfigId`: Makes a query live by sending through RTI stack.
|
|
57
|
+
* - `onSubscribe`: Callback to be called when a live query stream is started.
|
|
58
|
+
* - `onPause`: Callback to be called when a live query stream is paused, e.g. due to a network disconnection.
|
|
59
|
+
* - `onResume`: Callback to be called when a live query stream is resumed, e.g. from a network disconnection.
|
|
59
60
|
* - `metadata`: user-supplied metadata.
|
|
60
61
|
* - `transactionId`: a user-supplied value, intended for use as a unique id for
|
|
61
62
|
* a given instance of executing an operation.
|
|
@@ -65,6 +66,8 @@ export type CacheConfig = {
|
|
|
65
66
|
poll?: ?number,
|
|
66
67
|
liveConfigId?: ?string,
|
|
67
68
|
onSubscribe?: () => void,
|
|
69
|
+
onResume?: (pauseTimeMs: number) => void,
|
|
70
|
+
onPause?: (mqttConnectionIsOk: boolean, internetIsOk: boolean) => void,
|
|
68
71
|
metadata?: {[key: string]: mixed, ...},
|
|
69
72
|
transactionId?: ?string,
|
|
70
73
|
};
|
|
@@ -56,6 +56,7 @@ function getPaginationVariables(
|
|
|
56
56
|
...baseVariables,
|
|
57
57
|
...extraVariables,
|
|
58
58
|
[backwardMetadata.cursor]: cursor,
|
|
59
|
+
// $FlowFixMe[incompatible-type]
|
|
59
60
|
[backwardMetadata.count]: count,
|
|
60
61
|
};
|
|
61
62
|
if (forwardMetadata && forwardMetadata.cursor) {
|
|
@@ -92,6 +93,7 @@ function getPaginationVariables(
|
|
|
92
93
|
...baseVariables,
|
|
93
94
|
...extraVariables,
|
|
94
95
|
[forwardMetadata.cursor]: cursor,
|
|
96
|
+
// $FlowFixMe[incompatible-type]
|
|
95
97
|
[forwardMetadata.count]: count,
|
|
96
98
|
};
|
|
97
99
|
if (backwardMetadata && backwardMetadata.cursor) {
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
import type {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
FieldError,
|
|
16
|
+
FieldErrors,
|
|
17
17
|
IEnvironment,
|
|
18
18
|
} from '../store/RelayStoreTypes';
|
|
19
19
|
|
|
@@ -21,21 +21,32 @@ const invariant = require('invariant');
|
|
|
21
21
|
|
|
22
22
|
function handleFieldErrors(
|
|
23
23
|
environment: IEnvironment,
|
|
24
|
-
|
|
24
|
+
fieldErrors: FieldErrors,
|
|
25
|
+
loggingContext: mixed | void,
|
|
25
26
|
) {
|
|
26
|
-
for (const fieldError of
|
|
27
|
+
for (const fieldError of fieldErrors) {
|
|
27
28
|
// First we log all events. Note that the logger may opt to throw its own
|
|
28
29
|
// error here if it wants to throw an error that is better integrated into
|
|
29
30
|
// site's error handling infrastructure.
|
|
30
|
-
|
|
31
|
+
|
|
32
|
+
// Awkward. We don't want to attach the ui context in RelayReader where we
|
|
33
|
+
// create the event, but it means we need to add it here instead of just
|
|
34
|
+
// passing the event through.
|
|
35
|
+
|
|
36
|
+
environment.relayFieldLogger({
|
|
37
|
+
// the uiContext on fieldError undefined *always*,
|
|
38
|
+
...fieldError,
|
|
39
|
+
// and this is where we assign loggingContext to uiContext to populate it
|
|
40
|
+
uiContext: loggingContext,
|
|
41
|
+
});
|
|
31
42
|
}
|
|
32
43
|
|
|
33
|
-
for (const fieldError of
|
|
44
|
+
for (const fieldError of fieldErrors) {
|
|
34
45
|
if (eventShouldThrow(fieldError)) {
|
|
35
46
|
switch (fieldError.kind) {
|
|
36
47
|
case 'relay_resolver.error':
|
|
37
48
|
throw new Error(
|
|
38
|
-
`Relay: Resolver error at path '${fieldError.fieldPath}' in '${fieldError.owner}'
|
|
49
|
+
`Relay: Resolver error at path '${fieldError.fieldPath}' in '${fieldError.owner}'. Message: ${fieldError.error.message}`,
|
|
39
50
|
);
|
|
40
51
|
case 'relay_field_payload.error':
|
|
41
52
|
throw new Error(
|
|
@@ -63,7 +74,7 @@ function handleFieldErrors(
|
|
|
63
74
|
}
|
|
64
75
|
}
|
|
65
76
|
|
|
66
|
-
function eventShouldThrow(event:
|
|
77
|
+
function eventShouldThrow(event: FieldError): boolean {
|
|
67
78
|
switch (event.kind) {
|
|
68
79
|
case 'relay_resolver.error':
|
|
69
80
|
case 'relay_field_payload.error':
|
|
@@ -82,14 +93,15 @@ function eventShouldThrow(event: ErrorResponseField): boolean {
|
|
|
82
93
|
|
|
83
94
|
function handlePotentialSnapshotErrors(
|
|
84
95
|
environment: IEnvironment,
|
|
85
|
-
|
|
96
|
+
fieldErrors: ?FieldErrors,
|
|
97
|
+
loggingContext: mixed | void,
|
|
86
98
|
) {
|
|
87
99
|
/**
|
|
88
100
|
* Inside handleFieldErrors, we check for throwOnFieldError - but this fn logs the error anyway by default
|
|
89
101
|
* which is why this still should run in any case there's errors.
|
|
90
102
|
*/
|
|
91
|
-
if (
|
|
92
|
-
handleFieldErrors(environment,
|
|
103
|
+
if (fieldErrors != null) {
|
|
104
|
+
handleFieldErrors(environment, fieldErrors, loggingContext);
|
|
93
105
|
}
|
|
94
106
|
}
|
|
95
107
|
|
|
@@ -19,8 +19,10 @@ function registerEnvironmentWithDevTools(environment: IEnvironment): void {
|
|
|
19
19
|
const _global =
|
|
20
20
|
typeof global !== 'undefined'
|
|
21
21
|
? global
|
|
22
|
-
:
|
|
23
|
-
|
|
22
|
+
: // $FlowFixMe[cannot-resolve-name]
|
|
23
|
+
typeof window !== 'undefined'
|
|
24
|
+
? // $FlowFixMe[cannot-resolve-name]
|
|
25
|
+
window
|
|
24
26
|
: undefined;
|
|
25
27
|
|
|
26
28
|
// $FlowFixMe[incompatible-use] D61394600
|
|
@@ -30,6 +30,7 @@ function withProvidedVariables(
|
|
|
30
30
|
): Variables {
|
|
31
31
|
if (providedVariables != null) {
|
|
32
32
|
const operationVariables: {[string]: mixed} = {};
|
|
33
|
+
// $FlowFixMe[unsafe-object-assign]
|
|
33
34
|
Object.assign(operationVariables, userSuppliedVariables);
|
|
34
35
|
Object.keys(providedVariables).forEach((varName: string) => {
|
|
35
36
|
const providerFunction = providedVariables[varName].get;
|
|
@@ -12,11 +12,14 @@
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
14
|
const isPerformanceNowAvailable =
|
|
15
|
+
// $FlowFixMe[cannot-resolve-name]
|
|
15
16
|
typeof window !== 'undefined' &&
|
|
17
|
+
// $FlowFixMe[cannot-resolve-name]
|
|
16
18
|
typeof window?.performance?.now === 'function';
|
|
17
19
|
|
|
18
20
|
function currentTimestamp(): number {
|
|
19
21
|
if (isPerformanceNowAvailable) {
|
|
22
|
+
// $FlowFixMe[cannot-resolve-name]
|
|
20
23
|
return window.performance.now();
|
|
21
24
|
}
|
|
22
25
|
return Date.now();
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relay v18.2.0
|
|
3
|
-
*/
|
|
4
|
-
!function(e,r){"object"==typeof exports&&"object"==typeof module?module.exports=r(require("@babel/runtime/helpers/asyncToGenerator"),require("@babel/runtime/helpers/createForOfIteratorHelper"),require("@babel/runtime/helpers/defineProperty"),require("@babel/runtime/helpers/interopRequireDefault"),require("@babel/runtime/helpers/objectSpread2"),require("@babel/runtime/helpers/toConsumableArray"),require("fbjs/lib/areEqual"),require("fbjs/lib/warning"),require("invariant")):"function"==typeof define&&define.amd?define(["@babel/runtime/helpers/asyncToGenerator","@babel/runtime/helpers/createForOfIteratorHelper","@babel/runtime/helpers/defineProperty","@babel/runtime/helpers/interopRequireDefault","@babel/runtime/helpers/objectSpread2","@babel/runtime/helpers/toConsumableArray","fbjs/lib/areEqual","fbjs/lib/warning","invariant"],r):"object"==typeof exports?exports.ReactRelayExperimental=r(require("@babel/runtime/helpers/asyncToGenerator"),require("@babel/runtime/helpers/createForOfIteratorHelper"),require("@babel/runtime/helpers/defineProperty"),require("@babel/runtime/helpers/interopRequireDefault"),require("@babel/runtime/helpers/objectSpread2"),require("@babel/runtime/helpers/toConsumableArray"),require("fbjs/lib/areEqual"),require("fbjs/lib/warning"),require("invariant")):e.ReactRelayExperimental=r(e["@babel/runtime/helpers/asyncToGenerator"],e["@babel/runtime/helpers/createForOfIteratorHelper"],e["@babel/runtime/helpers/defineProperty"],e["@babel/runtime/helpers/interopRequireDefault"],e["@babel/runtime/helpers/objectSpread2"],e["@babel/runtime/helpers/toConsumableArray"],e["fbjs/lib/areEqual"],e["fbjs/lib/warning"],e.invariant)}(self,((e,r,t,n,a,o,i,u,l)=>(()=>{"use strict";var s={649:(e,r,t)=>{var n=t(662),a=t(696).observeFragment,o=t(461).waitForFragmentData;e.exports={resolverDataInjector:n,isValueResult:function(e){return!0===e.ok},isErrorResult:function(e){return!1===e.ok},observeFragment:a,waitForFragmentData:o}},60:(e,r,t)=>{var n=t(571),a=function(e,r){},o=function(){function e(e){if(!e||"function"!=typeof e)throw new Error("Source must be a Function: "+String(e));this._source=e}e.create=function(r){return new e(r)},e.onUnhandledError=function(e){a=e},e.from=function(e){return function(e){return"object"==typeof e&&null!==e&&"function"==typeof e.subscribe}(e)?i(e):n(e)?u(e):l(e)};var r=e.prototype;return r.catch=function(r){var t=this;return e.create((function(e){var n;return t.subscribe({start:function(e){n=e},next:e.next,complete:e.complete,error:function(t){try{r(t).subscribe({start:function(e){n=e},next:e.next,complete:e.complete,error:e.error})}catch(r){e.error(r,!0)}}}),function(){return n.unsubscribe()}}))},r.concat=function(r){var t=this;return e.create((function(e){var n;return t.subscribe({start:function(e){n=e},next:e.next,error:e.error,complete:function(){n=r.subscribe(e)}}),function(){n&&n.unsubscribe()}}))},r.do=function(r){var t=this;return e.create((function(e){var n=function(t){return function(){try{r[t]&&r[t].apply(r,arguments)}catch(e){a(e,!0)}e[t]&&e[t].apply(e,arguments)}};return t.subscribe({start:n("start"),next:n("next"),error:n("error"),complete:n("complete"),unsubscribe:n("unsubscribe")})}))},r.finally=function(r){var t=this;return e.create((function(e){var n=t.subscribe(e);return function(){n.unsubscribe(),r()}}))},r.ifEmpty=function(r){var t=this;return e.create((function(e){var n,a=!1;return n=t.subscribe({next:function(r){a=!0,e.next(r)},error:e.error,complete:function(){a?e.complete():n=r.subscribe(e)}}),function(){n&&n.unsubscribe()}}))},r.subscribe=function(e){if(!e||"object"!=typeof e)throw new Error("Observer must be an Object with callbacks: "+String(e));return function(e,r){var t,n=!1,o=function(e){return Object.defineProperty(e,"closed",{get:function(){return n}})};function i(){if(t){if(t.unsubscribe)t.unsubscribe();else try{t()}catch(e){a(e,!0)}t=void 0}}var u=o({unsubscribe:function(){if(!n){n=!0;try{r.unsubscribe&&r.unsubscribe(u)}catch(e){a(e,!0)}finally{i()}}}});try{r.start&&r.start(u)}catch(e){a(e,!0)}if(n)return u;var l=o({next:function(e){if(!n&&r.next)try{r.next(e)}catch(e){a(e,!0)}},error:function(e,t){if(n||!r.error)n=!0,a(e,t||!1),i();else{n=!0;try{r.error(e)}catch(e){a(e,!0)}finally{i()}}},complete:function(){if(!n){n=!0;try{r.complete&&r.complete()}catch(e){a(e,!0)}finally{i()}}}});try{t=e(l)}catch(e){l.error(e,!0)}if(void 0!==t&&"function"!=typeof t&&(!t||"function"!=typeof t.unsubscribe))throw new Error("Returned cleanup function which cannot be called: "+String(t));return n&&i(),u}(this._source,e)},r.map=function(r){var t=this;return e.create((function(e){var n=t.subscribe({complete:e.complete,error:e.error,next:function(t){try{var n=r(t);e.next(n)}catch(r){e.error(r,!0)}}});return function(){n.unsubscribe()}}))},r.mergeMap=function(r){var t=this;return e.create((function(n){var a=[];function o(e){this._sub=e,a.push(e)}function i(){a.splice(a.indexOf(this._sub),1),0===a.length&&n.complete()}return t.subscribe({start:o,next:function(t){try{n.closed||e.from(r(t)).subscribe({start:o,next:n.next,error:n.error,complete:i})}catch(e){n.error(e,!0)}},error:n.error,complete:i}),function(){a.forEach((function(e){return e.unsubscribe()})),a.length=0}}))},r.poll=function(r){var t=this;if("number"!=typeof r||r<=0)throw new Error("RelayObservable: Expected pollInterval to be positive, got: "+r);return e.create((function(e){var n,a;return function o(){n=t.subscribe({next:e.next,error:e.error,complete:function(){a=setTimeout(o,r)}})}(),function(){clearTimeout(a),n.unsubscribe()}}))},r.toPromise=function(){var e=this;return new Promise((function(r,t){var n=!1;e.subscribe({next:function(e){n||(n=!0,r(e))},error:t,complete:r})}))},e}();function i(e){return e instanceof o?e:o.create((function(r){return e.subscribe(r)}))}function u(e){return o.create((function(r){e.then((function(e){r.next(e),r.complete()}),r.error)}))}function l(e){return o.create((function(r){r.next(e),r.complete()}))}o.onUnhandledError((function(e,r){"function"==typeof fail?fail(String(e)):r?setTimeout((function(){throw e})):"undefined"!=typeof console&&console.error("RelayObservable: Unhandled Error",e)})),e.exports=o},634:(e,r,t)=>{var n=t(775),a=t(56),o=t(446);function i(e){var r=e;return"function"==typeof r?(r=r(),o(!1,"RelayGraphQLTag: node `%s` unexpectedly wrapped in a function.","Fragment"===r.kind?r.name:r.operation.name)):r.default&&(r=r.default),r}function u(e){var r=i(e);return"object"==typeof r&&null!==r&&r.kind===n.FRAGMENT}function l(e){var r=i(e);return"object"==typeof r&&null!==r&&r.kind===n.REQUEST}function s(e){var r=i(e);return"object"==typeof r&&null!==r&&r.kind===n.UPDATABLE_QUERY}function c(e){var r=i(e);return"object"==typeof r&&null!==r&&r.kind===n.INLINE_DATA_FRAGMENT}function f(e){var r=i(e);return u(r)||a(!1,"GraphQLTag: Expected a fragment, got `%s`.",JSON.stringify(r)),r}e.exports={getFragment:f,getNode:i,getPaginationFragment:function(e){var r,t=f(e),n=null===(r=t.metadata)||void 0===r?void 0:r.refetch,a=null==n?void 0:n.connection;return null===n||"object"!=typeof n||null===a||"object"!=typeof a?null:t},getRefetchableFragment:function(e){var r,t=f(e),n=null===(r=t.metadata)||void 0===r?void 0:r.refetch;return null===n||"object"!=typeof n?null:t},getRequest:function(e){var r=i(e);return l(r)||a(!1,"GraphQLTag: Expected a request, got `%s`.",JSON.stringify(r)),r},getUpdatableQuery:function(e){var r=i(e);return s(r)||a(!1,"GraphQLTag: Expected a request, got `%s`.",JSON.stringify(r)),r},getInlineDataFragment:function(e){var r=i(e);return c(r)||a(!1,"GraphQLTag: Expected an inline data fragment, got `%s`.",JSON.stringify(r)),r},graphql:function(e){a(!1,"graphql: Unexpected invocation at runtime. Either the Babel transform was not set up, or it failed to identify this call site. Make sure it is being used verbatim as `graphql`. Note also that there cannot be a space between graphql and the backtick that follows.")},isFragment:u,isRequest:l,isUpdatableQuery:s,isInlineDataFragment:c}},367:(e,r,t)=>{var n=t(60),a=t(153),o=t(56),i="function"==typeof WeakMap?new WeakMap:new Map;function u(e,r,t){return n.create((function(i){var u=s(e),l=u.get(r);return l||t().finally((function(){return u.delete(r)})).subscribe({start:function(e){l={identifier:r,subject:new a,subjectForInFlightStatus:new a,subscription:e,promise:null},u.set(r,l)},next:function(e){var t=c(u,r);t.subject.next(e),t.subjectForInFlightStatus.next(e)},error:function(e){var t=c(u,r);t.subject.error(e),t.subjectForInFlightStatus.error(e)},complete:function(){var e=c(u,r);e.subject.complete(),e.subjectForInFlightStatus.complete()},unsubscribe:function(e){var t=c(u,r);t.subject.unsubscribe(),t.subjectForInFlightStatus.unsubscribe()}}),null==l&&o(!1,"[fetchQueryInternal] fetchQueryDeduped: Expected `start` to be called synchronously"),function(e,r){return n.create((function(t){var n=r.subject.subscribe(t);return function(){n.unsubscribe();var t=e.get(r.identifier);if(t){var a=t.subscription;null!=a&&0===t.subject.getObserverCount()&&(a.unsubscribe(),e.delete(r.identifier))}}}))}(u,l).subscribe(i)}))}function l(e,r,t){return n.create((function(r){var n=t.subjectForInFlightStatus.subscribe({error:r.error,next:function(n){e.isRequestActive(t.identifier)?r.next():r.complete()},complete:r.complete,unsubscribe:r.complete});return function(){n.unsubscribe()}}))}function s(e){var r=i.get(e);if(null!=r)return r;var t=new Map;return i.set(e,t),t}function c(e,r){var t=e.get(r);return null==t&&o(!1,"[fetchQueryInternal] getCachedRequest: Expected request to be cached"),t}e.exports={fetchQuery:function(e,r){return u(e,r.request.identifier,(function(){return e.execute({operation:r})}))},fetchQueryDeduped:u,getPromiseForActiveRequest:function(e,r){var t=s(e).get(r.identifier);return t&&e.isRequestActive(t.identifier)?new Promise((function(r,n){var a=!1;l(e,0,t).subscribe({complete:r,error:n,next:function(e){a&&r(e)}}),a=!0})):null},getObservableForActiveRequest:function(e,r){var t=s(e).get(r.identifier);return t&&e.isRequestActive(t.identifier)?l(e,0,t):null}}},129:(e,r,t)=>{var n=(0,t(275).default)(t(175)),a=t(165).getArgumentValues,o=t(56);e.exports={getLocalVariables:function(e,r,t){if(null==r)return e;var o=(0,n.default)({},e),i=t?a(t,e):{};return r.forEach((function(e){var r,t=null!==(r=i[e.name])&&void 0!==r?r:e.defaultValue;o[e.name]=t})),o},getFragmentVariables:function(e,r,t){return null==e.argumentDefinitions?t:(e.argumentDefinitions.forEach((function(i){if(!t.hasOwnProperty(i.name))switch(a=a||(0,n.default)({},t),i.kind){case"LocalArgument":a[i.name]=i.defaultValue;break;case"RootArgument":if(!r.hasOwnProperty(i.name)){a[i.name]=void 0;break}a[i.name]=r[i.name];break;default:o(!1,"RelayConcreteVariables: Unexpected node kind `%s` in fragment `%s`.",i.kind,e.name)}})),a||t);var a},getOperationVariables:function(e,r,t){var n={};return e.argumentDefinitions.forEach((function(e){var r=e.defaultValue;null!=t[e.name]&&(r=t[e.name]),n[e.name]=r})),null!=r&&Object.keys(r).forEach((function(e){n[e]=r[e].get()})),n}}},256:(e,r,t)=>{var n=t(129).getFragmentVariables,a=t(165),o=a.CLIENT_EDGE_TRAVERSAL_PATH,i=a.FRAGMENT_OWNER_KEY,u=a.FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT,l=a.FRAGMENTS_KEY,s=a.ID_KEY,c=t(125),f=t(56),d=t(446);function p(e,r){("object"!=typeof r||null===r||Array.isArray(r))&&f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an object, got `%s`.",e.name,JSON.stringify(r));var t=r[s],a=r[l],c=r[i],p=r[o];if("string"==typeof t&&"object"==typeof a&&null!==a&&"object"==typeof a[e.name]&&null!==a[e.name]&&"object"==typeof c&&null!==c&&(null==p||Array.isArray(p))){var b=c,m=p,g=a[e.name];return R(e,t,n(e,b.variables,g),b,!0===g[u],m)}var v=JSON.stringify(r);return v.length>499&&(v=v.substr(0,498)+"…"),d(!1,"RelayModernSelector: Expected object to contain data for fragment `%s`, got `%s`. Make sure that the parent operation/fragment included fragment `...%s` without `@relay(mask: false)`.",e.name,v,e.name),null}function b(e,r){var t=null;return r.forEach((function(r,n){var a=null!=r?p(e,r):null;null!=a&&(t=t||[]).push(a)})),null==t?null:{kind:"PluralReaderSelector",selectors:t}}function m(e,r){return null==r?r:e.metadata&&!0===e.metadata.plural?(Array.isArray(r)||f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.",e.name,JSON.stringify(r),e.name),b(e,r)):(Array.isArray(r)&&f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an object, got `%s`. Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.",e.name,JSON.stringify(r),e.name),p(e,r))}function g(e,r){return null==r?r:e.metadata&&!0===e.metadata.plural?(Array.isArray(r)||f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.",e.name,JSON.stringify(r),e.name),function(e,r){var t=null;return r.forEach((function(r){var n=null!=r?v(e,r):null;null!=n&&(t=t||[]).push(n)})),t}(e,r)):(Array.isArray(r)&&f(!1,"RelayModernFragmentSpecResolver: Expected value for fragment `%s` to be an object, got `%s`. Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.",e.name,JSON.stringify(r),e.name),v(e,r))}function v(e,r){("object"!=typeof r||null===r||Array.isArray(r))&&f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an object, got `%s`.",e.name,JSON.stringify(r));var t=r[s];return"string"==typeof t?t:(d(!1,"RelayModernSelector: Expected object to contain data for fragment `%s`, got `%s`. Make sure that the parent operation/fragment included fragment `...%s` without `@relay(mask: false)`, or `null` is passed as the fragment reference for `%s` if it's conditonally included and the condition isn't met.",e.name,JSON.stringify(r),e.name,e.name),null)}function h(e,r){var t;return null==r?{}:!0===(null===(t=e.metadata)||void 0===t?void 0:t.plural)?(Array.isArray(r)||f(!1,"RelayModernSelector: Expected value for fragment `%s` to be an array, got `%s`. Remove `@relay(plural: true)` from fragment `%s` to allow the prop to be an object.",e.name,JSON.stringify(r),e.name),y(e,r)):(Array.isArray(r)&&f(!1,"RelayModernFragmentSpecResolver: Expected value for fragment `%s` to be an object, got `%s`. Add `@relay(plural: true)` to fragment `%s` to allow the prop to be an array of items.",e.name,JSON.stringify(r),e.name),E(e,r)||{})}function E(e,r){var t=p(e,r);return t?t.variables:null}function y(e,r){var t={};return r.forEach((function(r,n){if(null!=r){var a=E(e,r);null!=a&&Object.assign(t,a)}})),t}function _(e,r){return e.dataID===r.dataID&&e.node===r.node&&c(e.variables,r.variables)&&((t=e.owner)===(n=r.owner)||t.identifier===n.identifier&&c(t.cacheConfig,n.cacheConfig))&&e.isWithinUnmatchedTypeRefinement===r.isWithinUnmatchedTypeRefinement&&function(e,r){if(e===r)return!0;if(null==e||null==r||e.length!==r.length)return!1;for(var t=e.length;t--;){var n=e[t],a=r[t];if(n!==a&&(null==n||null==a||n.clientEdgeDestinationID!==a.clientEdgeDestinationID||n.readerClientEdge!==a.readerClientEdge))return!1}return!0}(e.clientEdgeTraversalPath,r.clientEdgeTraversalPath);var t,n}function R(e,r,t,n){var a=arguments.length>5?arguments[5]:void 0;return{kind:"SingularReaderSelector",dataID:r,isWithinUnmatchedTypeRefinement:arguments.length>4&&void 0!==arguments[4]&&arguments[4],clientEdgeTraversalPath:null!=a?a:null,node:e,variables:t,owner:n}}e.exports={areEqualSelectors:function(e,r){return e===r||(null==e?null==r:null==r?null==e:"SingularReaderSelector"===e.kind&&"SingularReaderSelector"===r.kind?_(e,r):"PluralReaderSelector"===e.kind&&"PluralReaderSelector"===r.kind&&e.selectors.length===r.selectors.length&&e.selectors.every((function(e,t){return _(e,r.selectors[t])})))},createReaderSelector:R,createNormalizationSelector:function(e,r,t){return{dataID:r,node:e,variables:t}},getDataIDsFromFragment:g,getDataIDsFromObject:function(e,r){var t={};for(var n in e)if(e.hasOwnProperty(n)){var a=e[n],o=r[n];t[n]=g(a,o)}return t},getSingularSelector:p,getPluralSelector:b,getSelector:m,getSelectorsFromObject:function(e,r){var t={};for(var n in e)if(e.hasOwnProperty(n)){var a=e[n],o=r[n];t[n]=m(a,o)}return t},getVariablesFromSingularFragment:E,getVariablesFromPluralFragment:y,getVariablesFromFragment:h,getVariablesFromObject:function(e,r){var t={};for(var n in e)if(e.hasOwnProperty(n)){var a=h(e[n],r[n]);Object.assign(t,a)}return t}}},165:(e,r,t)=>{var n=(0,t(275).default)(t(642)),a=t(330),o=t(775),i=t(94).stableCopy,u=t(56),l=o.VARIABLE,s=o.LITERAL,c=o.OBJECT_VALUE,f=o.LIST_VALUE;function d(e,r){if(e.kind===l)return function(e,r){return r.hasOwnProperty(e)||u(!1,"getVariableValue(): Undefined variable `%s`.",e),i(r[e])}(e.variableName,r);if(e.kind===s)return e.value;if(e.kind===c){var t={};return e.fields.forEach((function(e){t[e.name]=d(e,r)})),t}if(e.kind===f){var n=[];return e.items.forEach((function(e){null!=e&&n.push(d(e,r))})),n}}function p(e,r,t){var n={};return t&&(n[m.FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT]=!0),e&&e.forEach((function(e){n[e.name]=d(e,r)})),n}function b(e,r){if(!r)return e;var t=[];for(var n in r)if(r.hasOwnProperty(n)){var a,o=r[n];null!=o&&t.push(n+":"+(null!==(a=JSON.stringify(o))&&void 0!==a?a:"undefined"))}return 0===t.length?e:e+"(".concat(t.join(","),")")}var m={ACTOR_IDENTIFIER_KEY:"__actorIdentifier",CLIENT_EDGE_TRAVERSAL_PATH:"__clientEdgeTraversalPath",FRAGMENTS_KEY:"__fragments",FRAGMENT_OWNER_KEY:"__fragmentOwner",FRAGMENT_POINTER_IS_WITHIN_UNMATCHED_TYPE_REFINEMENT:"$isWithinUnmatchedTypeRefinement",FRAGMENT_PROP_NAME_KEY:"__fragmentPropName",MODULE_COMPONENT_KEY:"__module_component",ERRORS_KEY:"__errors",ID_KEY:"__id",REF_KEY:"__ref",REFS_KEY:"__refs",ROOT_ID:"client:root",ROOT_TYPE:"__Root",TYPENAME_KEY:"__typename",INVALIDATED_AT_KEY:"__invalidated_at",RELAY_RESOLVER_VALUE_KEY:"__resolverValue",RELAY_RESOLVER_INVALIDATION_KEY:"__resolverValueMayBeInvalid",RELAY_RESOLVER_SNAPSHOT_KEY:"__resolverSnapshot",RELAY_RESOLVER_ERROR_KEY:"__resolverError",RELAY_RESOLVER_OUTPUT_TYPE_RECORD_IDS:"__resolverOutputTypeRecordIDs",formatStorageKey:b,getArgumentValue:d,getArgumentValues:p,getHandleStorageKey:function(e,r){var t=e.dynamicKey,o=e.handle,i=e.key,u=e.name,l=e.args,s=e.filters,c=a(o,i,u),f=null;return l&&s&&0!==l.length&&0!==s.length&&(f=l.filter((function(e){return s.indexOf(e.name)>-1}))),t&&(f=null!=f?[t].concat((0,n.default)(f)):[t]),null===f?c:b(c,p(f,r))},getStorageKey:function(e,r){if(e.storageKey)return e.storageKey;var t=function(e){var r,t;return"RelayResolver"===e.kind||"RelayLiveResolver"===e.kind?null==e.args?null===(t=e.fragment)||void 0===t?void 0:t.args:null==(null===(r=e.fragment)||void 0===r?void 0:r.args)?e.args:e.args.concat(e.fragment.args):void 0===e.args?void 0:e.args}(e),n=e.name;return t&&0!==t.length?b(n,p(t,r)):n},getStableStorageKey:function(e,r){return b(e,i(r))},getModuleComponentKey:function(e){return"".concat("__module_component_").concat(e)},getModuleOperationKey:function(e){return"".concat("__module_operation_").concat(e)}};e.exports=m},890:(e,r,t)=>{var n=t(634).getFragment,a=t(222).eventShouldThrow,o=t(256).getSelector,i=t(56),u=[],l={};e.exports={readFragment:function(e,r){if(!u.length)throw new Error("readFragment should be called only from within a Relay Resolver function.");var t=u[u.length-1],s=n(e),c=o(s,r);null==c&&i(!1,"Expected a selector for the fragment of the resolver ".concat(s.name,", but got null.")),"SingularReaderSelector"!==c.kind&&i(!1,"Expected a singular reader selector for the fragment of the resolver ".concat(s.name,", but it was plural."));var f=t.getDataForResolverFragment(c,r),d=f.data,p=f.isMissingData,b=f.errorResponseFields;if(p||null!=b&&b.some(a))throw l;return d},withResolverContext:function(e,r){u.push(e);try{return r()}finally{u.pop()}},RESOLVER_FRAGMENT_ERRORED_SENTINEL:l}},662:(e,r,t)=>{var n=t(890).readFragment,a=t(56);e.exports=function(e,r,t,o){var i=r;return function(r,u){var l=n(e,r);if(null==t)return i(l,u);if(null==l){if(!0!==o)return i(null,u);a(!1,"Expected required resolver field `%s` in fragment `%s` to be present. But resolvers fragment data is null/undefined.",t,e.name)}if(t in l)return!0===o&&null==l[t]&&a(!1,"Expected required resolver field `%s` in fragment `%s` to be non-null.",t,e.name),i(l[t],u);a(!1,"Missing field `%s` in fragment `%s` in resolver response.",t,e.name)}}},696:(e,r,t)=>{var n=t(314).default,a=t(60),o=t(634).getFragment,i=t(250),u=t(222).handlePotentialSnapshotErrors,l=t(256).getSelector,s=t(56);function c(){return(c=n((function*(e,r,t){var n;try{var a,o=yield new Promise((function(a,o){n=f(e,r,t).subscribe({next:function(e){"ok"===e.state?a(e.value):"error"===e.state&&o(e.error)}})}));return null===(a=n)||void 0===a||a.unsubscribe(),o}catch(e){var i;throw null===(i=n)||void 0===i||i.unsubscribe(),e}}))).apply(this,arguments)}function f(e,r,t){var n,i=o(r),u=l(i,t);switch(null!=(null===(n=i.metadata)||void 0===n?void 0:n.hasClientEdges)&&s(!1,"Client edges aren't supported yet."),null==u&&s(!1,"Expected a selector, got null."),u.kind){case"SingularReaderSelector":return function(e,r,t){var n=e.lookup(t);return a.create((function(a){a.next(d(e,r,t.owner,n));var o=e.subscribe(n,(function(n){a.next(d(e,r,t.owner,n))}));return function(){return o.dispose()}}))}(e,r,u);case"PluralReaderSelector":s(!1,"Plural fragments are not supported")}s(!1,"Unsupported fragment selector kind")}function d(e,r,t,n){var a=null!=n.missingLiveResolverFields&&n.missingLiveResolverFields.length>0,o=null!=n.missingClientEdges&&n.missingClientEdges.length>0;if(a||o)return{state:"loading"};if(n.isMissingData&&null!=i(e,r,t))return{state:"loading"};try{u(e,n.errorResponseFields)}catch(e){return{error:e,state:"error"}}return null==n.data&&s(!1,"Expected data to be non-null."),{state:"ok",value:n.data}}e.exports={observeFragment:f,waitForFragmentData:function(e,r,t){return c.apply(this,arguments)}}},461:(e,r,t)=>{var n=t(314).default,a=t(696).observeFragment;function o(){return(o=n((function*(e,r,t){var n;try{var o,i=yield new Promise((function(o,i){n=a(e,r,t).subscribe({next:function(e){"ok"===e.state?o(e.value):"error"===e.state&&i(e.error)}})}));return null===(o=n)||void 0===o||o.unsubscribe(),i}catch(e){var u;throw null===(u=n)||void 0===u||u.unsubscribe(),e}}))).apply(this,arguments)}e.exports={waitForFragmentData:function(e,r,t){return o.apply(this,arguments)}}},775:e=>{e.exports={ACTOR_CHANGE:"ActorChange",CATCH_FIELD:"CatchField",CONDITION:"Condition",CLIENT_COMPONENT:"ClientComponent",CLIENT_EDGE_TO_SERVER_OBJECT:"ClientEdgeToServerObject",CLIENT_EDGE_TO_CLIENT_OBJECT:"ClientEdgeToClientObject",CLIENT_EXTENSION:"ClientExtension",DEFER:"Defer",CONNECTION:"Connection",FRAGMENT:"Fragment",FRAGMENT_SPREAD:"FragmentSpread",INLINE_DATA_FRAGMENT_SPREAD:"InlineDataFragmentSpread",INLINE_DATA_FRAGMENT:"InlineDataFragment",INLINE_FRAGMENT:"InlineFragment",LINKED_FIELD:"LinkedField",LINKED_HANDLE:"LinkedHandle",LITERAL:"Literal",LIST_VALUE:"ListValue",LOCAL_ARGUMENT:"LocalArgument",MODULE_IMPORT:"ModuleImport",ALIASED_FRAGMENT_SPREAD:"AliasedFragmentSpread",ALIASED_INLINE_FRAGMENT_SPREAD:"AliasedInlineFragmentSpread",RELAY_RESOLVER:"RelayResolver",RELAY_LIVE_RESOLVER:"RelayLiveResolver",REQUIRED_FIELD:"RequiredField",OBJECT_VALUE:"ObjectValue",OPERATION:"Operation",REQUEST:"Request",ROOT_ARGUMENT:"RootArgument",SCALAR_FIELD:"ScalarField",SCALAR_HANDLE:"ScalarHandle",SPLIT_OPERATION:"SplitOperation",STREAM:"Stream",TYPE_DISCRIMINATOR:"TypeDiscriminator",UPDATABLE_QUERY:"UpdatableQuery",VARIABLE:"Variable"}},204:e=>{e.exports={DEFAULT_HANDLE_KEY:""}},153:(e,r,t)=>{var n=t(275).default,a=n(t(765)),o=n(t(311)),i=t(60),u=t(56),l=function(){function e(){var e=this;(0,o.default)(this,"_complete",!1),(0,o.default)(this,"_events",[]),(0,o.default)(this,"_sinks",new Set),(0,o.default)(this,"_subscription",[]),this._observable=i.create((function(r){e._sinks.add(r);for(var t=e._events,n=0;n<t.length&&!r.closed;n++){var a=t[n];switch(a.kind){case"complete":r.complete();break;case"error":r.error(a.error);break;case"next":r.next(a.data);break;default:a.kind,u(!1,"RelayReplaySubject: Unknown event kind `%s`.",a.kind)}}return function(){e._sinks.delete(r)}}))}var r=e.prototype;return r.complete=function(){!0!==this._complete&&(this._complete=!0,this._events.push({kind:"complete"}),this._sinks.forEach((function(e){return e.complete()})))},r.error=function(e){!0!==this._complete&&(this._complete=!0,this._events.push({kind:"error",error:e}),this._sinks.forEach((function(r){return r.error(e)})))},r.next=function(e){!0!==this._complete&&(this._events.push({kind:"next",data:e}),this._sinks.forEach((function(r){return r.next(e)})))},r.subscribe=function(e){var r=this._observable.subscribe(e);return this._subscription.push(r),r},r.unsubscribe=function(){var e,r=(0,a.default)(this._subscription);try{for(r.s();!(e=r.n()).done;)e.value.unsubscribe()}catch(e){r.e(e)}finally{r.f()}this._subscription=[]},r.getObserverCount=function(){return this._sinks.size},e}();e.exports=l},250:(e,r,t)=>{var n=t(367).getPromiseForActiveRequest;e.exports=function(e,r,t){var a,o,i=[],u=n(e,t);if(null!=u)i=[t];else{var l,s,c=e.getOperationTracker().getPendingOperationsAffectingOwner(t);i=null!==(l=null==c?void 0:c.pendingOperations)&&void 0!==l?l:[],u=null!==(s=null==c?void 0:c.promise)&&void 0!==s?s:null}if(!u)return null;var f=null!==(a=null===(o=i)||void 0===o?void 0:o.map((function(e){return e.node.params.name})).join(","))&&void 0!==a?a:null;null!=f&&0!==f.length||(f="Unknown pending operation");var d=r.name,p=f===d?"Relay(".concat(f,")"):"Relay(".concat(f,":").concat(d,")");return u.displayName=p,e.__log({name:"pendingoperation.found",fragment:r,fragmentOwner:t,pendingOperations:i}),{promise:u,pendingOperations:i}}},330:(e,r,t)=>{var n=t(204).DEFAULT_HANDLE_KEY,a=t(56);e.exports=function(e,r,t){return r&&r!==n?"__".concat(r,"_").concat(e):(null==t&&a(!1,"getRelayHandleKey: Expected either `fieldName` or `key` in `handle` to be provided"),"__".concat(t,"_").concat(e))}},222:(e,r,t)=>{var n=(0,t(275).default)(t(765)),a=t(56);function o(e){switch(e.kind){case"relay_resolver.error":case"relay_field_payload.error":return e.shouldThrow&&!e.handled;case"missing_expected_data.throw":case"missing_required_field.throw":return!e.handled;case"missing_required_field.log":case"missing_expected_data.log":return!1;default:throw e.kind,new Error("Relay: Unexpected event kind")}}e.exports={handlePotentialSnapshotErrors:function(e,r){null!=r&&function(e,r){var t,i=(0,n.default)(r);try{for(i.s();!(t=i.n()).done;){var u=t.value;e.relayFieldLogger(u)}}catch(e){i.e(e)}finally{i.f()}var l,s=(0,n.default)(r);try{for(s.s();!(l=s.n()).done;){var c=l.value;if(o(c))switch(c.kind){case"relay_resolver.error":throw new Error("Relay: Resolver error at path '".concat(c.fieldPath,"' in '").concat(c.owner,"'."));case"relay_field_payload.error":throw new Error("Relay: Unexpected response payload - check server logs for details.");case"missing_expected_data.throw":throw new Error("Relay: Missing expected data at path '".concat(c.fieldPath,"' in '").concat(c.owner,"'."));case"missing_required_field.throw":throw new Error("Relay: Missing @required value at path '".concat(c.fieldPath,"' in '").concat(c.owner,"'."));case"missing_required_field.log":case"missing_expected_data.log":break;default:c.kind,a(!1,"Relay: Unexpected event kind: %s",c.kind)}}}catch(e){s.e(e)}finally{s.f()}}(e,r)},eventShouldThrow:o}},571:e=>{e.exports=function(e){return null!=e&&"object"==typeof e&&"function"==typeof e.then}},94:e=>{e.exports={stableCopy:function e(r){if(!r||"object"!=typeof r)return r;if(Array.isArray(r))return r.map(e);for(var t=Object.keys(r).sort(),n={},a=0;a<t.length;a++)n[t[a]]=e(r[t[a]]);return n},hasCycle:function e(r){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:new Set;if(!r||"object"!=typeof r)return!1;if(t.has(r))return!0;var n=new Set(t);return n.add(r),(Array.isArray(r)?r:Object.values(r)).some((function(r){return e(r,n)}))}}},314:r=>{r.exports=e},765:e=>{e.exports=r},311:e=>{e.exports=t},275:e=>{e.exports=n},175:e=>{e.exports=a},642:e=>{e.exports=o},125:e=>{e.exports=i},446:e=>{e.exports=u},56:e=>{e.exports=l}},c={};return function e(r){var t=c[r];if(void 0!==t)return t.exports;var n=c[r]={exports:{}};return s[r](n,n.exports,e),n.exports}(649)})()));
|