relay-runtime 11.0.2 → 12.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/index.js +1 -1
- package/index.js.flow +16 -1
- package/lib/index.js +15 -0
- package/lib/multi-actor-environment/ActorIdentifier.js +11 -1
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +59 -19
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +305 -55
- package/lib/multi-actor-environment/index.js +5 -1
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +6 -1
- package/lib/mutations/commitMutation.js +4 -1
- package/lib/mutations/validateMutation.js +6 -1
- package/lib/network/RelayObservable.js +3 -1
- package/lib/network/RelayQueryResponseCache.js +19 -3
- package/lib/network/wrapNetworkWithLogObserver.js +78 -0
- package/lib/store/DataChecker.js +110 -40
- package/lib/store/OperationExecutor.js +478 -204
- package/lib/store/RelayConcreteVariables.js +21 -0
- package/lib/store/RelayModernEnvironment.js +41 -85
- package/lib/store/RelayModernFragmentSpecResolver.js +48 -22
- package/lib/store/RelayModernRecord.js +35 -1
- package/lib/store/RelayModernStore.js +48 -14
- package/lib/store/RelayOperationTracker.js +33 -23
- package/lib/store/RelayPublishQueue.js +23 -5
- package/lib/store/RelayReader.js +138 -44
- package/lib/store/RelayRecordSource.js +87 -3
- package/lib/store/RelayReferenceMarker.js +28 -15
- package/lib/store/RelayResponseNormalizer.js +164 -91
- package/lib/store/RelayStoreReactFlightUtils.js +1 -7
- package/lib/store/RelayStoreSubscriptions.js +8 -5
- package/lib/store/RelayStoreUtils.js +7 -2
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +1 -1
- package/lib/store/createRelayContext.js +1 -1
- package/lib/subscription/requestSubscription.js +27 -29
- package/lib/util/RelayConcreteNode.js +1 -0
- package/lib/util/RelayFeatureFlags.js +3 -5
- package/lib/util/RelayReplaySubject.js +21 -6
- package/lib/util/getPaginationMetadata.js +41 -0
- package/lib/util/getPaginationVariables.js +67 -0
- package/lib/util/getPendingOperationsForFragment.js +55 -0
- package/lib/util/getRefetchMetadata.js +36 -0
- package/lib/util/getValueAtPath.js +51 -0
- package/lib/util/isEmptyObject.js +1 -1
- package/lib/util/registerEnvironmentWithDevTools.js +26 -0
- package/lib/util/withDuration.js +31 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +17 -1
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +72 -44
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +332 -80
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +61 -12
- package/multi-actor-environment/index.js.flow +3 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -2
- package/mutations/commitMutation.js.flow +2 -0
- package/mutations/validateMutation.js.flow +8 -0
- package/network/RelayObservable.js.flow +2 -0
- package/network/RelayQueryResponseCache.js.flow +31 -18
- package/network/wrapNetworkWithLogObserver.js.flow +99 -0
- package/package.json +1 -1
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +5 -1
- package/store/DataChecker.js.flow +126 -35
- package/store/OperationExecutor.js.flow +528 -265
- package/store/RelayConcreteVariables.js.flow +26 -1
- package/store/RelayModernEnvironment.js.flow +41 -94
- package/store/RelayModernFragmentSpecResolver.js.flow +40 -14
- package/store/RelayModernOperationDescriptor.js.flow +9 -3
- package/store/RelayModernRecord.js.flow +49 -0
- package/store/RelayModernStore.js.flow +50 -12
- package/store/RelayOperationTracker.js.flow +56 -34
- package/store/RelayPublishQueue.js.flow +31 -8
- package/store/RelayReader.js.flow +148 -42
- package/store/RelayRecordSource.js.flow +72 -6
- package/store/RelayReferenceMarker.js.flow +29 -12
- package/store/RelayResponseNormalizer.js.flow +164 -48
- package/store/RelayStoreReactFlightUtils.js.flow +1 -7
- package/store/RelayStoreSubscriptions.js.flow +10 -3
- package/store/RelayStoreTypes.js.flow +128 -12
- package/store/RelayStoreUtils.js.flow +17 -3
- package/store/ResolverCache.js.flow +247 -0
- package/store/ResolverFragments.js.flow +6 -3
- package/store/createRelayContext.js.flow +1 -1
- package/subscription/requestSubscription.js.flow +41 -29
- package/util/NormalizationNode.js.flow +10 -3
- package/util/ReaderNode.js.flow +15 -1
- package/util/RelayConcreteNode.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +8 -10
- package/util/RelayReplaySubject.js.flow +7 -6
- package/util/getPaginationMetadata.js.flow +74 -0
- package/util/getPaginationVariables.js.flow +112 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +80 -0
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +1 -0
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/withDuration.js.flow +32 -0
- package/lib/store/RelayRecordSourceMapImpl.js +0 -107
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
- package/store/RelayRecordSourceMapImpl.js.flow +0 -91
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
|
@@ -18,7 +18,6 @@ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
|
18
18
|
const warning = require('warning');
|
|
19
19
|
|
|
20
20
|
const {getRequest} = require('../query/GraphQLTag');
|
|
21
|
-
const {generateUniqueClientID} = require('../store/ClientID');
|
|
22
21
|
const {
|
|
23
22
|
createOperationDescriptor,
|
|
24
23
|
} = require('../store/RelayModernOperationDescriptor');
|
|
@@ -36,7 +35,24 @@ import type {
|
|
|
36
35
|
Variables,
|
|
37
36
|
} from '../util/RelayRuntimeTypes';
|
|
38
37
|
|
|
39
|
-
export type
|
|
38
|
+
export type SubscriptionParameters = {|
|
|
39
|
+
+response: {...},
|
|
40
|
+
+variables: interface {},
|
|
41
|
+
+rawResponse?: {...},
|
|
42
|
+
|};
|
|
43
|
+
|
|
44
|
+
export type GraphQLSubscriptionConfig<T: SubscriptionParameters> = {|
|
|
45
|
+
configs?: Array<DeclarativeMutationConfig>,
|
|
46
|
+
cacheConfig?: CacheConfig,
|
|
47
|
+
subscription: GraphQLTaggedNode,
|
|
48
|
+
variables: $ElementType<T, 'variables'>,
|
|
49
|
+
onCompleted?: ?() => void,
|
|
50
|
+
onError?: ?(error: Error) => void,
|
|
51
|
+
onNext?: ?(response: ?$ElementType<T, 'response'>) => void,
|
|
52
|
+
updater?: ?SelectorStoreUpdater,
|
|
53
|
+
|};
|
|
54
|
+
|
|
55
|
+
export type DEPRECATED_GraphQLSubscriptionConfig<TSubscriptionPayload> = {|
|
|
40
56
|
configs?: Array<DeclarativeMutationConfig>,
|
|
41
57
|
cacheConfig?: CacheConfig,
|
|
42
58
|
subscription: GraphQLTaggedNode,
|
|
@@ -49,7 +65,7 @@ export type GraphQLSubscriptionConfig<TSubscriptionPayload> = {|
|
|
|
49
65
|
|
|
50
66
|
function requestSubscription<TSubscriptionPayload>(
|
|
51
67
|
environment: IEnvironment,
|
|
52
|
-
config:
|
|
68
|
+
config: DEPRECATED_GraphQLSubscriptionConfig<TSubscriptionPayload>,
|
|
53
69
|
): Disposable {
|
|
54
70
|
const subscription = getRequest(config.subscription);
|
|
55
71
|
if (subscription.params.operationKind !== 'subscription') {
|
|
@@ -67,9 +83,6 @@ function requestSubscription<TSubscriptionPayload>(
|
|
|
67
83
|
subscription,
|
|
68
84
|
variables,
|
|
69
85
|
cacheConfig,
|
|
70
|
-
RelayFeatureFlags.ENABLE_UNIQUE_SUBSCRIPTION_ROOT
|
|
71
|
-
? generateUniqueClientID()
|
|
72
|
-
: undefined,
|
|
73
86
|
);
|
|
74
87
|
|
|
75
88
|
warning(
|
|
@@ -91,30 +104,29 @@ function requestSubscription<TSubscriptionPayload>(
|
|
|
91
104
|
operation,
|
|
92
105
|
updater,
|
|
93
106
|
})
|
|
94
|
-
.map(responses => {
|
|
95
|
-
let selector = operation.fragment;
|
|
96
|
-
if (RelayFeatureFlags.ENABLE_UNIQUE_SUBSCRIPTION_ROOT) {
|
|
97
|
-
let nextID;
|
|
98
|
-
if (Array.isArray(responses)) {
|
|
99
|
-
nextID = responses[0]?.extensions?.__relay_subscription_root_id;
|
|
100
|
-
} else {
|
|
101
|
-
nextID = responses.extensions?.__relay_subscription_root_id;
|
|
102
|
-
}
|
|
103
|
-
if (typeof nextID === 'string') {
|
|
104
|
-
selector = createReaderSelector(
|
|
105
|
-
selector.node,
|
|
106
|
-
nextID,
|
|
107
|
-
selector.variables,
|
|
108
|
-
selector.owner,
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
const data = environment.lookup(selector).data;
|
|
113
|
-
// $FlowFixMe[incompatible-cast]
|
|
114
|
-
return (data: TSubscriptionPayload);
|
|
115
|
-
})
|
|
116
107
|
.subscribe({
|
|
117
|
-
next:
|
|
108
|
+
next: responses => {
|
|
109
|
+
if (onNext != null) {
|
|
110
|
+
let selector = operation.fragment;
|
|
111
|
+
let nextID;
|
|
112
|
+
if (Array.isArray(responses)) {
|
|
113
|
+
nextID = responses[0]?.extensions?.__relay_subscription_root_id;
|
|
114
|
+
} else {
|
|
115
|
+
nextID = responses.extensions?.__relay_subscription_root_id;
|
|
116
|
+
}
|
|
117
|
+
if (typeof nextID === 'string') {
|
|
118
|
+
selector = createReaderSelector(
|
|
119
|
+
selector.node,
|
|
120
|
+
nextID,
|
|
121
|
+
selector.variables,
|
|
122
|
+
selector.owner,
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
const data = environment.lookup(selector).data;
|
|
126
|
+
// $FlowFixMe[incompatible-cast]
|
|
127
|
+
onNext((data: TSubscriptionPayload));
|
|
128
|
+
}
|
|
129
|
+
},
|
|
118
130
|
error: onError,
|
|
119
131
|
complete: onCompleted,
|
|
120
132
|
});
|
|
@@ -87,7 +87,7 @@ export type NormalizationInlineFragment = {|
|
|
|
87
87
|
|
|
88
88
|
export type NormalizationFragmentSpread = {|
|
|
89
89
|
+kind: 'FragmentSpread',
|
|
90
|
-
+fragment:
|
|
90
|
+
+fragment: NormalizationSplitOperation,
|
|
91
91
|
+args: ?$ReadOnlyArray<NormalizationArgument>,
|
|
92
92
|
|};
|
|
93
93
|
|
|
@@ -102,7 +102,13 @@ export type NormalizationLinkedField = {|
|
|
|
102
102
|
+selections: $ReadOnlyArray<NormalizationSelection>,
|
|
103
103
|
|};
|
|
104
104
|
|
|
105
|
+
export type NormalizationActorChange = {|
|
|
106
|
+
+kind: 'ActorChange',
|
|
107
|
+
+linkedField: NormalizationLinkedField,
|
|
108
|
+
|};
|
|
109
|
+
|
|
105
110
|
export type NormalizationModuleImport = {|
|
|
111
|
+
+args: ?$ReadOnlyArray<NormalizationArgument>,
|
|
106
112
|
+kind: 'ModuleImport',
|
|
107
113
|
+documentName: string,
|
|
108
114
|
+fragmentPropName: string,
|
|
@@ -155,6 +161,7 @@ export type NormalizationFlightField = {|
|
|
|
155
161
|
|};
|
|
156
162
|
|
|
157
163
|
export type NormalizationClientComponent = {|
|
|
164
|
+
+args?: ?$ReadOnlyArray<NormalizationArgument>,
|
|
158
165
|
+kind: 'ClientComponent',
|
|
159
166
|
+fragment: NormalizationNode,
|
|
160
167
|
|};
|
|
@@ -176,9 +183,11 @@ export type NormalizationSelection =
|
|
|
176
183
|
| NormalizationInlineFragment
|
|
177
184
|
| NormalizationModuleImport
|
|
178
185
|
| NormalizationStream
|
|
186
|
+
| NormalizationActorChange
|
|
179
187
|
| NormalizationTypeDiscriminator;
|
|
180
188
|
|
|
181
189
|
export type NormalizationSplitOperation = {|
|
|
190
|
+
+argumentDefinitions?: $ReadOnlyArray<NormalizationLocalArgumentDefinition>,
|
|
182
191
|
+kind: 'SplitOperation',
|
|
183
192
|
+name: string,
|
|
184
193
|
+metadata: ?{+[key: string]: mixed, ...},
|
|
@@ -189,8 +198,6 @@ export type NormalizationStream = {|
|
|
|
189
198
|
+if: string | null,
|
|
190
199
|
+kind: 'Stream',
|
|
191
200
|
+label: string,
|
|
192
|
-
+useCustomizedBatch: string | null,
|
|
193
|
-
+metadata: ?{+[key: string]: mixed, ...},
|
|
194
201
|
+selections: $ReadOnlyArray<NormalizationSelection>,
|
|
195
202
|
|};
|
|
196
203
|
|
package/util/ReaderNode.js.flow
CHANGED
|
@@ -108,7 +108,10 @@ export type ReaderClientExtension = {|
|
|
|
108
108
|
+selections: $ReadOnlyArray<ReaderSelection>,
|
|
109
109
|
|};
|
|
110
110
|
|
|
111
|
-
export type ReaderField =
|
|
111
|
+
export type ReaderField =
|
|
112
|
+
| ReaderScalarField
|
|
113
|
+
| ReaderLinkedField
|
|
114
|
+
| ReaderRelayResolver;
|
|
112
115
|
|
|
113
116
|
export type ReaderRootArgument = {|
|
|
114
117
|
+kind: 'RootArgument',
|
|
@@ -133,7 +136,17 @@ export type ReaderLinkedField = {|
|
|
|
133
136
|
+selections: $ReadOnlyArray<ReaderSelection>,
|
|
134
137
|
|};
|
|
135
138
|
|
|
139
|
+
export type ReaderActorChange = {|
|
|
140
|
+
+kind: 'ActorChange',
|
|
141
|
+
+alias: ?string,
|
|
142
|
+
+name: string,
|
|
143
|
+
+storageKey: ?string,
|
|
144
|
+
+args: ?$ReadOnlyArray<ReaderArgument>,
|
|
145
|
+
+fragmentSpread: ReaderFragmentSpread,
|
|
146
|
+
|};
|
|
147
|
+
|
|
136
148
|
export type ReaderModuleImport = {|
|
|
149
|
+
+args?: ?$ReadOnlyArray<ReaderArgument>,
|
|
137
150
|
+kind: 'ModuleImport',
|
|
138
151
|
+documentName: string,
|
|
139
152
|
+fragmentPropName: string,
|
|
@@ -223,6 +236,7 @@ export type ReaderSelection =
|
|
|
223
236
|
| ReaderClientExtension
|
|
224
237
|
| ReaderDefer
|
|
225
238
|
| ReaderField
|
|
239
|
+
| ReaderActorChange
|
|
226
240
|
| ReaderFlightField
|
|
227
241
|
| ReaderFragmentSpread
|
|
228
242
|
| ReaderInlineDataFragmentSpread
|
|
@@ -12,40 +12,38 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
+
import type {Disposable} from '../util/RelayRuntimeTypes';
|
|
16
|
+
|
|
15
17
|
type FeatureFlags = {|
|
|
16
18
|
ENABLE_VARIABLE_CONNECTION_KEY: boolean,
|
|
17
19
|
ENABLE_PARTIAL_RENDERING_DEFAULT: boolean,
|
|
18
|
-
ENABLE_RELAY_CONTAINERS_SUSPENSE: boolean,
|
|
19
|
-
ENABLE_PRECISE_TYPE_REFINEMENT: boolean,
|
|
20
20
|
ENABLE_REACT_FLIGHT_COMPONENT_FIELD: boolean,
|
|
21
21
|
ENABLE_REQUIRED_DIRECTIVES: boolean | string,
|
|
22
22
|
ENABLE_RELAY_RESOLVERS: boolean,
|
|
23
23
|
ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION: boolean,
|
|
24
24
|
ENABLE_FRIENDLY_QUERY_NAME_GQL_URL: boolean,
|
|
25
|
-
ENABLE_STORE_SUBSCRIPTIONS_REFACTOR: boolean,
|
|
26
25
|
ENABLE_LOAD_QUERY_REQUEST_DEDUPING: boolean,
|
|
27
26
|
ENABLE_DO_NOT_WRAP_LIVE_QUERY: boolean,
|
|
28
27
|
ENABLE_NOTIFY_SUBSCRIPTION: boolean,
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
BATCH_ASYNC_MODULE_UPDATES_FN: ?(() => void) => Disposable,
|
|
29
|
+
ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: boolean,
|
|
30
|
+
ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: boolean,
|
|
31
31
|
|};
|
|
32
32
|
|
|
33
33
|
const RelayFeatureFlags: FeatureFlags = {
|
|
34
34
|
ENABLE_VARIABLE_CONNECTION_KEY: false,
|
|
35
35
|
ENABLE_PARTIAL_RENDERING_DEFAULT: true,
|
|
36
|
-
ENABLE_RELAY_CONTAINERS_SUSPENSE: true,
|
|
37
|
-
ENABLE_PRECISE_TYPE_REFINEMENT: false,
|
|
38
36
|
ENABLE_REACT_FLIGHT_COMPONENT_FIELD: false,
|
|
39
37
|
ENABLE_REQUIRED_DIRECTIVES: false,
|
|
40
38
|
ENABLE_RELAY_RESOLVERS: false,
|
|
41
39
|
ENABLE_GETFRAGMENTIDENTIFIER_OPTIMIZATION: false,
|
|
42
40
|
ENABLE_FRIENDLY_QUERY_NAME_GQL_URL: false,
|
|
43
|
-
ENABLE_STORE_SUBSCRIPTIONS_REFACTOR: false,
|
|
44
41
|
ENABLE_LOAD_QUERY_REQUEST_DEDUPING: true,
|
|
45
42
|
ENABLE_DO_NOT_WRAP_LIVE_QUERY: false,
|
|
46
43
|
ENABLE_NOTIFY_SUBSCRIPTION: false,
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
BATCH_ASYNC_MODULE_UPDATES_FN: null,
|
|
45
|
+
ENABLE_CONTAINERS_SUBSCRIBE_ON_COMMIT: false,
|
|
46
|
+
ENABLE_QUERY_RENDERER_OFFSCREEN_SUPPORT: false,
|
|
49
47
|
};
|
|
50
48
|
|
|
51
49
|
module.exports = RelayFeatureFlags;
|
|
@@ -42,7 +42,7 @@ class RelayReplaySubject<T> {
|
|
|
42
42
|
_events: Array<Event<T>> = [];
|
|
43
43
|
_sinks: Set<Sink<T>> = new Set();
|
|
44
44
|
_observable: RelayObservable<T>;
|
|
45
|
-
_subscription:
|
|
45
|
+
_subscription: Array<Subscription> = [];
|
|
46
46
|
|
|
47
47
|
constructor() {
|
|
48
48
|
this._observable = RelayObservable.create(sink => {
|
|
@@ -116,15 +116,16 @@ class RelayReplaySubject<T> {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
subscribe(observer: Observer<T> | Sink<T>): Subscription {
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
const subscription = this._observable.subscribe(observer);
|
|
120
|
+
this._subscription.push(subscription);
|
|
121
|
+
return subscription;
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
unsubscribe() {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this._subscription = null;
|
|
125
|
+
for (const subscription of this._subscription) {
|
|
126
|
+
subscription.unsubscribe();
|
|
127
127
|
}
|
|
128
|
+
this._subscription = [];
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
getObserverCount(): number {
|
|
@@ -0,0 +1,74 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const getRefetchMetadata = require('./getRefetchMetadata');
|
|
17
|
+
const invariant = require('invariant');
|
|
18
|
+
|
|
19
|
+
import type {
|
|
20
|
+
ConcreteRequest,
|
|
21
|
+
ReaderFragment,
|
|
22
|
+
ReaderPaginationMetadata,
|
|
23
|
+
} from 'relay-runtime';
|
|
24
|
+
|
|
25
|
+
function getPaginationMetadata(
|
|
26
|
+
fragmentNode: ReaderFragment,
|
|
27
|
+
componentDisplayName: string,
|
|
28
|
+
): {|
|
|
29
|
+
connectionPathInFragmentData: $ReadOnlyArray<string | number>,
|
|
30
|
+
identifierField: ?string,
|
|
31
|
+
paginationRequest: ConcreteRequest,
|
|
32
|
+
paginationMetadata: ReaderPaginationMetadata,
|
|
33
|
+
stream: boolean,
|
|
34
|
+
|} {
|
|
35
|
+
const {
|
|
36
|
+
refetchableRequest: paginationRequest,
|
|
37
|
+
refetchMetadata,
|
|
38
|
+
} = getRefetchMetadata(fragmentNode, componentDisplayName);
|
|
39
|
+
|
|
40
|
+
const paginationMetadata = refetchMetadata.connection;
|
|
41
|
+
invariant(
|
|
42
|
+
paginationMetadata != null,
|
|
43
|
+
'Relay: getPaginationMetadata(): Expected fragment `%s` to include a ' +
|
|
44
|
+
'connection when using `%s`. Did you forget to add a @connection ' +
|
|
45
|
+
'directive to the connection field in the fragment?',
|
|
46
|
+
componentDisplayName,
|
|
47
|
+
fragmentNode.name,
|
|
48
|
+
);
|
|
49
|
+
const connectionPathInFragmentData = paginationMetadata.path;
|
|
50
|
+
|
|
51
|
+
const connectionMetadata = (fragmentNode.metadata?.connection ?? [])[0];
|
|
52
|
+
invariant(
|
|
53
|
+
connectionMetadata != null,
|
|
54
|
+
'Relay: getPaginationMetadata(): Expected fragment `%s` to include a ' +
|
|
55
|
+
'connection when using `%s`. Did you forget to add a @connection ' +
|
|
56
|
+
'directive to the connection field in the fragment?',
|
|
57
|
+
componentDisplayName,
|
|
58
|
+
fragmentNode.name,
|
|
59
|
+
);
|
|
60
|
+
const identifierField = refetchMetadata.identifierField;
|
|
61
|
+
invariant(
|
|
62
|
+
identifierField == null || typeof identifierField === 'string',
|
|
63
|
+
'Relay: getRefetchMetadata(): Expected `identifierField` to be a string.',
|
|
64
|
+
);
|
|
65
|
+
return {
|
|
66
|
+
connectionPathInFragmentData,
|
|
67
|
+
identifierField,
|
|
68
|
+
paginationRequest,
|
|
69
|
+
paginationMetadata,
|
|
70
|
+
stream: connectionMetadata.stream === true,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
module.exports = getPaginationMetadata;
|
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const invariant = require('invariant');
|
|
17
|
+
const warning = require('warning');
|
|
18
|
+
|
|
19
|
+
import type {ReaderPaginationMetadata} from './ReaderNode';
|
|
20
|
+
import type {Variables} from './RelayRuntimeTypes';
|
|
21
|
+
|
|
22
|
+
export type Direction = 'forward' | 'backward';
|
|
23
|
+
|
|
24
|
+
function getPaginationVariables(
|
|
25
|
+
direction: Direction,
|
|
26
|
+
count: number,
|
|
27
|
+
cursor: ?string,
|
|
28
|
+
baseVariables: Variables,
|
|
29
|
+
extraVariables: Variables,
|
|
30
|
+
paginationMetadata: ReaderPaginationMetadata,
|
|
31
|
+
): {[string]: mixed, ...} {
|
|
32
|
+
const {
|
|
33
|
+
backward: backwardMetadata,
|
|
34
|
+
forward: forwardMetadata,
|
|
35
|
+
} = paginationMetadata;
|
|
36
|
+
|
|
37
|
+
if (direction === 'backward') {
|
|
38
|
+
invariant(
|
|
39
|
+
backwardMetadata != null &&
|
|
40
|
+
backwardMetadata.count != null &&
|
|
41
|
+
backwardMetadata.cursor != null,
|
|
42
|
+
'Relay: Expected backward pagination metadata to be available. ' +
|
|
43
|
+
"If you're seeing this, this is likely a bug in Relay.",
|
|
44
|
+
);
|
|
45
|
+
warning(
|
|
46
|
+
!extraVariables.hasOwnProperty(backwardMetadata.cursor),
|
|
47
|
+
'Relay: `UNSTABLE_extraVariables` provided by caller should not ' +
|
|
48
|
+
'contain cursor variable `%s`. This variable is automatically ' +
|
|
49
|
+
'determined by Relay.',
|
|
50
|
+
backwardMetadata.cursor,
|
|
51
|
+
);
|
|
52
|
+
warning(
|
|
53
|
+
!extraVariables.hasOwnProperty(backwardMetadata.count),
|
|
54
|
+
'Relay: `UNSTABLE_extraVariables` provided by caller should not ' +
|
|
55
|
+
'contain count variable `%s`. This variable is automatically ' +
|
|
56
|
+
'determined by Relay.',
|
|
57
|
+
backwardMetadata.count,
|
|
58
|
+
);
|
|
59
|
+
// $FlowFixMe[cannot-spread-interface]
|
|
60
|
+
const paginationVariables = {
|
|
61
|
+
...baseVariables,
|
|
62
|
+
...extraVariables,
|
|
63
|
+
[backwardMetadata.cursor]: cursor,
|
|
64
|
+
[backwardMetadata.count]: count,
|
|
65
|
+
};
|
|
66
|
+
if (forwardMetadata && forwardMetadata.cursor) {
|
|
67
|
+
paginationVariables[forwardMetadata.cursor] = null;
|
|
68
|
+
}
|
|
69
|
+
if (forwardMetadata && forwardMetadata.count) {
|
|
70
|
+
paginationVariables[forwardMetadata.count] = null;
|
|
71
|
+
}
|
|
72
|
+
return paginationVariables;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
invariant(
|
|
76
|
+
forwardMetadata != null &&
|
|
77
|
+
forwardMetadata.count != null &&
|
|
78
|
+
forwardMetadata.cursor != null,
|
|
79
|
+
'Relay: Expected forward pagination metadata to be available. ' +
|
|
80
|
+
"If you're seeing this, this is likely a bug in Relay.",
|
|
81
|
+
);
|
|
82
|
+
warning(
|
|
83
|
+
!extraVariables.hasOwnProperty(forwardMetadata.cursor),
|
|
84
|
+
'Relay: `UNSTABLE_extraVariables` provided by caller should not ' +
|
|
85
|
+
'contain cursor variable `%s`. This variable is automatically ' +
|
|
86
|
+
'determined by Relay.',
|
|
87
|
+
forwardMetadata.cursor,
|
|
88
|
+
);
|
|
89
|
+
warning(
|
|
90
|
+
!extraVariables.hasOwnProperty(forwardMetadata.count),
|
|
91
|
+
'Relay: `UNSTABLE_extraVariables` provided by caller should not ' +
|
|
92
|
+
'contain count variable `%s`. This variable is automatically ' +
|
|
93
|
+
'determined by Relay.',
|
|
94
|
+
forwardMetadata.count,
|
|
95
|
+
);
|
|
96
|
+
// $FlowFixMe[cannot-spread-interface]
|
|
97
|
+
const paginationVariables = {
|
|
98
|
+
...baseVariables,
|
|
99
|
+
...extraVariables,
|
|
100
|
+
[forwardMetadata.cursor]: cursor,
|
|
101
|
+
[forwardMetadata.count]: count,
|
|
102
|
+
};
|
|
103
|
+
if (backwardMetadata && backwardMetadata.cursor) {
|
|
104
|
+
paginationVariables[backwardMetadata.cursor] = null;
|
|
105
|
+
}
|
|
106
|
+
if (backwardMetadata && backwardMetadata.count) {
|
|
107
|
+
paginationVariables[backwardMetadata.count] = null;
|
|
108
|
+
}
|
|
109
|
+
return paginationVariables;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = getPaginationVariables;
|
|
@@ -0,0 +1,62 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const {getPromiseForActiveRequest} = require('../query/fetchQueryInternal');
|
|
17
|
+
|
|
18
|
+
import type {IEnvironment, RequestDescriptor} from '../store/RelayStoreTypes';
|
|
19
|
+
import type {ReaderFragment} from './ReaderNode';
|
|
20
|
+
|
|
21
|
+
function getPendingOperationsForFragment(
|
|
22
|
+
environment: IEnvironment,
|
|
23
|
+
fragmentNode: ReaderFragment,
|
|
24
|
+
fragmentOwner: RequestDescriptor,
|
|
25
|
+
): {|
|
|
26
|
+
promise: Promise<void>,
|
|
27
|
+
pendingOperations: $ReadOnlyArray<RequestDescriptor>,
|
|
28
|
+
|} | null {
|
|
29
|
+
let pendingOperations: $ReadOnlyArray<RequestDescriptor> = [];
|
|
30
|
+
let promise = getPromiseForActiveRequest(environment, fragmentOwner);
|
|
31
|
+
|
|
32
|
+
if (promise != null) {
|
|
33
|
+
pendingOperations = [fragmentOwner];
|
|
34
|
+
} else {
|
|
35
|
+
const result = environment
|
|
36
|
+
.getOperationTracker()
|
|
37
|
+
.getPendingOperationsAffectingOwner(fragmentOwner);
|
|
38
|
+
|
|
39
|
+
pendingOperations = result?.pendingOperations ?? [];
|
|
40
|
+
promise = result?.promise ?? null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!promise) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let pendingOperationName =
|
|
48
|
+
pendingOperations?.map(op => op.node.params.name).join(',') ?? null;
|
|
49
|
+
if (pendingOperationName == null || pendingOperationName.length === 0) {
|
|
50
|
+
pendingOperationName = 'Unknown pending operation';
|
|
51
|
+
}
|
|
52
|
+
const fragmentName = fragmentNode.name;
|
|
53
|
+
const promiseDisplayName =
|
|
54
|
+
pendingOperationName === fragmentName
|
|
55
|
+
? `Relay(${pendingOperationName})`
|
|
56
|
+
: `Relay(${pendingOperationName}:${fragmentName})`;
|
|
57
|
+
// $FlowExpectedError[prop-missing] Expando to annotate Promises.
|
|
58
|
+
promise.displayName = promiseDisplayName;
|
|
59
|
+
return {promise, pendingOperations};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = getPendingOperationsForFragment;
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const invariant = require('invariant');
|
|
17
|
+
|
|
18
|
+
import type {
|
|
19
|
+
ConcreteRequest,
|
|
20
|
+
ReaderFragment,
|
|
21
|
+
ReaderRefetchMetadata,
|
|
22
|
+
} from 'relay-runtime';
|
|
23
|
+
|
|
24
|
+
function getRefetchMetadata(
|
|
25
|
+
fragmentNode: ReaderFragment,
|
|
26
|
+
componentDisplayName: string,
|
|
27
|
+
): {|
|
|
28
|
+
fragmentRefPathInResponse: $ReadOnlyArray<string | number>,
|
|
29
|
+
identifierField: ?string,
|
|
30
|
+
refetchableRequest: ConcreteRequest,
|
|
31
|
+
refetchMetadata: ReaderRefetchMetadata,
|
|
32
|
+
|} {
|
|
33
|
+
invariant(
|
|
34
|
+
fragmentNode.metadata?.plural !== true,
|
|
35
|
+
'Relay: getRefetchMetadata(): Expected fragment `%s` not to be plural when using ' +
|
|
36
|
+
'`%s`. Remove `@relay(plural: true)` from fragment `%s` ' +
|
|
37
|
+
'in order to use it with `%s`.',
|
|
38
|
+
fragmentNode.name,
|
|
39
|
+
componentDisplayName,
|
|
40
|
+
fragmentNode.name,
|
|
41
|
+
componentDisplayName,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const refetchMetadata = fragmentNode.metadata?.refetch;
|
|
45
|
+
invariant(
|
|
46
|
+
refetchMetadata != null,
|
|
47
|
+
'Relay: getRefetchMetadata(): Expected fragment `%s` to be refetchable when using `%s`. ' +
|
|
48
|
+
'Did you forget to add a @refetchable directive to the fragment?',
|
|
49
|
+
componentDisplayName,
|
|
50
|
+
fragmentNode.name,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
// handle both commonjs and es modules
|
|
54
|
+
const refetchableRequest:
|
|
55
|
+
| ConcreteRequest
|
|
56
|
+
| string = (refetchMetadata: $FlowFixMe).operation.default
|
|
57
|
+
? (refetchMetadata: $FlowFixMe).operation.default
|
|
58
|
+
: refetchMetadata.operation;
|
|
59
|
+
const fragmentRefPathInResponse = refetchMetadata.fragmentPathInResult;
|
|
60
|
+
invariant(
|
|
61
|
+
typeof refetchableRequest !== 'string',
|
|
62
|
+
'Relay: getRefetchMetadata(): Expected refetch query to be an ' +
|
|
63
|
+
"operation and not a string when using `%s`. If you're seeing this, " +
|
|
64
|
+
'this is likely a bug in Relay.',
|
|
65
|
+
componentDisplayName,
|
|
66
|
+
);
|
|
67
|
+
const identifierField = refetchMetadata.identifierField;
|
|
68
|
+
invariant(
|
|
69
|
+
identifierField == null || typeof identifierField === 'string',
|
|
70
|
+
'Relay: getRefetchMetadata(): Expected `identifierField` to be a string.',
|
|
71
|
+
);
|
|
72
|
+
return {
|
|
73
|
+
fragmentRefPathInResponse,
|
|
74
|
+
identifierField,
|
|
75
|
+
refetchableRequest,
|
|
76
|
+
refetchMetadata,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
module.exports = getRefetchMetadata;
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow strict-local
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// flowlint ambiguous-object-type:error
|
|
13
|
+
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
const invariant = require('invariant');
|
|
17
|
+
|
|
18
|
+
function getValueAtPath(
|
|
19
|
+
data: mixed,
|
|
20
|
+
path: $ReadOnlyArray<string | number>,
|
|
21
|
+
): mixed {
|
|
22
|
+
let result = data;
|
|
23
|
+
for (const key of path) {
|
|
24
|
+
if (result == null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
if (typeof key === 'number') {
|
|
28
|
+
invariant(
|
|
29
|
+
Array.isArray(result),
|
|
30
|
+
'Relay: Expected an array when extracting value at path. ' +
|
|
31
|
+
"If you're seeing this, this is likely a bug in Relay.",
|
|
32
|
+
);
|
|
33
|
+
result = result[key];
|
|
34
|
+
} else {
|
|
35
|
+
invariant(
|
|
36
|
+
typeof result === 'object' && !Array.isArray(result),
|
|
37
|
+
'Relay: Expected an object when extracting value at path. ' +
|
|
38
|
+
"If you're seeing this, this is likely a bug in Relay.",
|
|
39
|
+
);
|
|
40
|
+
result = result[key];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = getValueAtPath;
|