relay-runtime 11.0.1 → 13.0.0-rc.1
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/handlers/RelayDefaultHandlerProvider.js.flow +2 -2
- package/handlers/connection/ConnectionHandler.js.flow +8 -17
- package/handlers/connection/MutationHandlers.js.flow +7 -11
- package/index.js +1 -1
- package/index.js.flow +60 -36
- package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
- package/lib/handlers/connection/ConnectionHandler.js +13 -19
- package/lib/handlers/connection/MutationHandlers.js +4 -7
- package/lib/index.js +58 -43
- package/lib/multi-actor-environment/ActorIdentifier.js +33 -0
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +152 -0
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +419 -0
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +11 -0
- package/lib/multi-actor-environment/index.js +21 -0
- package/lib/mutations/RelayDeclarativeMutationConfig.js +4 -1
- package/lib/mutations/RelayRecordProxy.js +3 -2
- package/lib/mutations/RelayRecordSourceMutator.js +3 -2
- package/lib/mutations/RelayRecordSourceProxy.js +12 -4
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +18 -5
- package/lib/mutations/applyOptimisticMutation.js +6 -6
- package/lib/mutations/commitMutation.js +14 -10
- package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +238 -0
- package/lib/mutations/validateMutation.js +10 -5
- package/lib/network/ConvertToExecuteFunction.js +2 -1
- package/lib/network/RelayNetwork.js +3 -2
- package/lib/network/RelayQueryResponseCache.js +21 -5
- package/lib/network/wrapNetworkWithLogObserver.js +79 -0
- package/lib/query/GraphQLTag.js +3 -2
- package/lib/query/fetchQuery.js +6 -5
- package/lib/query/fetchQueryInternal.js +1 -1
- package/lib/query/fetchQuery_DEPRECATED.js +2 -1
- package/lib/store/ClientID.js +7 -1
- package/lib/store/DataChecker.js +123 -54
- package/lib/store/{RelayModernQueryExecutor.js → OperationExecutor.js} +518 -200
- package/lib/store/RelayConcreteVariables.js +26 -8
- package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
- package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
- package/lib/store/RelayModernEnvironment.js +175 -240
- package/lib/store/RelayModernFragmentSpecResolver.js +52 -26
- package/lib/store/RelayModernOperationDescriptor.js +2 -1
- package/lib/store/RelayModernRecord.js +47 -12
- package/lib/store/RelayModernSelector.js +14 -8
- package/lib/store/RelayModernStore.js +56 -28
- package/lib/store/RelayOperationTracker.js +34 -24
- package/lib/store/RelayPublishQueue.js +41 -13
- package/lib/store/RelayReader.js +288 -48
- package/lib/store/RelayRecordSource.js +87 -3
- package/lib/store/RelayReferenceMarker.js +34 -22
- package/lib/store/RelayResponseNormalizer.js +211 -110
- package/lib/store/RelayStoreReactFlightUtils.js +4 -10
- package/lib/store/RelayStoreSubscriptions.js +14 -9
- package/lib/store/RelayStoreUtils.js +12 -7
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +61 -0
- package/lib/store/cloneRelayHandleSourceField.js +5 -4
- package/lib/store/cloneRelayScalarHandleSourceField.js +5 -4
- package/lib/store/createRelayContext.js +4 -2
- package/lib/store/readInlineData.js +6 -2
- package/lib/subscription/requestSubscription.js +34 -25
- package/lib/util/RelayConcreteNode.js +3 -0
- package/lib/util/RelayFeatureFlags.js +10 -4
- package/lib/util/RelayProfiler.js +17 -187
- package/lib/util/RelayReplaySubject.js +22 -7
- package/lib/util/RelayRuntimeTypes.js +0 -6
- package/lib/util/StringInterner.js +71 -0
- package/lib/util/getFragmentIdentifier.js +15 -7
- package/lib/util/getOperation.js +2 -1
- package/lib/util/getPaginationMetadata.js +41 -0
- package/lib/util/getPaginationVariables.js +66 -0
- package/lib/util/getPendingOperationsForFragment.js +55 -0
- package/lib/util/getRefetchMetadata.js +36 -0
- package/lib/util/getRelayHandleKey.js +2 -2
- package/lib/util/getRequestIdentifier.js +2 -2
- 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 +43 -0
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +225 -0
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +506 -0
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +261 -0
- package/multi-actor-environment/index.js.flow +26 -0
- package/mutations/RelayDeclarativeMutationConfig.js.flow +32 -26
- package/mutations/RelayRecordProxy.js.flow +4 -5
- package/mutations/RelayRecordSourceMutator.js.flow +4 -6
- package/mutations/RelayRecordSourceProxy.js.flow +19 -10
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +22 -7
- package/mutations/applyOptimisticMutation.js.flow +13 -14
- package/mutations/commitLocalUpdate.js.flow +1 -1
- package/mutations/commitMutation.js.flow +35 -46
- package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +309 -0
- package/mutations/validateMutation.js.flow +26 -16
- package/network/ConvertToExecuteFunction.js.flow +2 -2
- package/network/RelayNetwork.js.flow +4 -5
- package/network/RelayNetworkTypes.js.flow +5 -4
- package/network/RelayObservable.js.flow +1 -1
- package/network/RelayQueryResponseCache.js.flow +34 -21
- package/network/wrapNetworkWithLogObserver.js.flow +100 -0
- package/package.json +3 -2
- package/query/GraphQLTag.js.flow +9 -9
- package/query/PreloadableQueryRegistry.js.flow +2 -1
- package/query/fetchQuery.js.flow +11 -13
- package/query/fetchQueryInternal.js.flow +6 -9
- package/query/fetchQuery_DEPRECATED.js.flow +6 -6
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +14 -3
- package/store/DataChecker.js.flow +141 -59
- package/store/{RelayModernQueryExecutor.js.flow → OperationExecutor.js.flow} +605 -303
- package/store/RelayConcreteVariables.js.flow +27 -8
- package/store/RelayExperimentalGraphResponseHandler.js.flow +124 -0
- package/store/RelayExperimentalGraphResponseTransform.js.flow +475 -0
- package/store/RelayModernEnvironment.js.flow +173 -240
- package/store/RelayModernFragmentSpecResolver.js.flow +55 -31
- package/store/RelayModernOperationDescriptor.js.flow +12 -7
- package/store/RelayModernRecord.js.flow +67 -11
- package/store/RelayModernSelector.js.flow +24 -14
- package/store/RelayModernStore.js.flow +66 -36
- package/store/RelayOperationTracker.js.flow +59 -43
- package/store/RelayOptimisticRecordSource.js.flow +2 -2
- package/store/RelayPublishQueue.js.flow +79 -34
- package/store/RelayReader.js.flow +351 -73
- package/store/RelayRecordSource.js.flow +72 -6
- package/store/RelayReferenceMarker.js.flow +40 -26
- package/store/RelayResponseNormalizer.js.flow +258 -99
- package/store/RelayStoreReactFlightUtils.js.flow +4 -11
- package/store/RelayStoreSubscriptions.js.flow +19 -11
- package/store/RelayStoreTypes.js.flow +209 -43
- package/store/RelayStoreUtils.js.flow +24 -11
- package/store/ResolverCache.js.flow +249 -0
- package/store/ResolverFragments.js.flow +121 -0
- package/store/StoreInspector.js.flow +2 -2
- package/store/TypeID.js.flow +1 -1
- package/store/ViewerPattern.js.flow +2 -2
- package/store/cloneRelayHandleSourceField.js.flow +5 -6
- package/store/cloneRelayScalarHandleSourceField.js.flow +5 -6
- package/store/createFragmentSpecResolver.js.flow +3 -4
- package/store/createRelayContext.js.flow +3 -3
- package/store/normalizeRelayPayload.js.flow +6 -7
- package/store/readInlineData.js.flow +7 -8
- package/subscription/requestSubscription.js.flow +53 -41
- package/util/NormalizationNode.js.flow +10 -3
- package/util/ReaderNode.js.flow +38 -2
- package/util/RelayConcreteNode.js.flow +5 -0
- package/util/RelayFeatureFlags.js.flow +24 -10
- package/util/RelayProfiler.js.flow +22 -194
- package/util/RelayReplaySubject.js.flow +9 -9
- package/util/RelayRuntimeTypes.js.flow +72 -3
- package/util/StringInterner.js.flow +69 -0
- package/util/createPayloadFor3DField.js.flow +3 -3
- package/util/getFragmentIdentifier.js.flow +27 -15
- package/util/getOperation.js.flow +2 -2
- package/util/getPaginationMetadata.js.flow +72 -0
- package/util/getPaginationVariables.js.flow +108 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +79 -0
- package/util/getRelayHandleKey.js.flow +1 -2
- package/util/getRequestIdentifier.js.flow +3 -3
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +1 -0
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/resolveImmediate.js.flow +1 -1
- 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
|
@@ -0,0 +1,249 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
import type {ReaderRelayResolver} from '../util/ReaderNode';
|
|
16
|
+
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
17
|
+
import type {
|
|
18
|
+
MutableRecordSource,
|
|
19
|
+
Record,
|
|
20
|
+
SingularReaderSelector,
|
|
21
|
+
} from './RelayStoreTypes';
|
|
22
|
+
|
|
23
|
+
const recycleNodesInto = require('../util/recycleNodesInto');
|
|
24
|
+
const {generateClientID} = require('./ClientID');
|
|
25
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
26
|
+
const {
|
|
27
|
+
RELAY_RESOLVER_INPUTS_KEY,
|
|
28
|
+
RELAY_RESOLVER_INVALIDATION_KEY,
|
|
29
|
+
RELAY_RESOLVER_READER_SELECTOR_KEY,
|
|
30
|
+
RELAY_RESOLVER_VALUE_KEY,
|
|
31
|
+
getStorageKey,
|
|
32
|
+
} = require('./RelayStoreUtils');
|
|
33
|
+
const warning = require('warning');
|
|
34
|
+
|
|
35
|
+
type ResolverID = string;
|
|
36
|
+
|
|
37
|
+
type EvaluationResult<T> = {|
|
|
38
|
+
resolverResult: T,
|
|
39
|
+
fragmentValue: {...},
|
|
40
|
+
resolverID: ResolverID,
|
|
41
|
+
seenRecordIDs: Set<DataID>,
|
|
42
|
+
readerSelector: SingularReaderSelector,
|
|
43
|
+
|};
|
|
44
|
+
|
|
45
|
+
export interface ResolverCache {
|
|
46
|
+
readFromCacheOrEvaluate<T>(
|
|
47
|
+
record: Record,
|
|
48
|
+
field: ReaderRelayResolver,
|
|
49
|
+
variables: Variables,
|
|
50
|
+
evaluate: () => EvaluationResult<T>,
|
|
51
|
+
getDataForResolverFragment: (SingularReaderSelector) => mixed,
|
|
52
|
+
): [T /* Answer */, ?DataID /* Seen record */];
|
|
53
|
+
invalidateDataIDs(
|
|
54
|
+
updatedDataIDs: Set<DataID>, // Mutated in place
|
|
55
|
+
): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// $FlowFixMe[unclear-type] - will always be empty
|
|
59
|
+
const emptySet: $ReadOnlySet<any> = new Set();
|
|
60
|
+
|
|
61
|
+
class NoopResolverCache implements ResolverCache {
|
|
62
|
+
readFromCacheOrEvaluate<T>(
|
|
63
|
+
record: Record,
|
|
64
|
+
field: ReaderRelayResolver,
|
|
65
|
+
variables: Variables,
|
|
66
|
+
evaluate: () => EvaluationResult<T>,
|
|
67
|
+
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
68
|
+
): [T /* Answer */, ?DataID /* Seen record */] {
|
|
69
|
+
return [evaluate().resolverResult, undefined];
|
|
70
|
+
}
|
|
71
|
+
invalidateDataIDs(updatedDataIDs: Set<DataID>): void {}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function addDependencyEdge(
|
|
75
|
+
edges: Map<ResolverID, Set<DataID>> | Map<DataID, Set<ResolverID>>,
|
|
76
|
+
from: ResolverID | DataID,
|
|
77
|
+
to: ResolverID | DataID,
|
|
78
|
+
): void {
|
|
79
|
+
let set = edges.get(from);
|
|
80
|
+
if (!set) {
|
|
81
|
+
set = new Set();
|
|
82
|
+
edges.set(from, set);
|
|
83
|
+
}
|
|
84
|
+
set.add(to);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
class RecordResolverCache implements ResolverCache {
|
|
88
|
+
_resolverIDToRecordIDs: Map<ResolverID, Set<DataID>>;
|
|
89
|
+
_recordIDToResolverIDs: Map<DataID, Set<ResolverID>>;
|
|
90
|
+
|
|
91
|
+
_getRecordSource: () => MutableRecordSource;
|
|
92
|
+
|
|
93
|
+
constructor(getRecordSource: () => MutableRecordSource) {
|
|
94
|
+
this._resolverIDToRecordIDs = new Map();
|
|
95
|
+
this._recordIDToResolverIDs = new Map();
|
|
96
|
+
this._getRecordSource = getRecordSource;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
readFromCacheOrEvaluate<T>(
|
|
100
|
+
record: Record,
|
|
101
|
+
field: ReaderRelayResolver,
|
|
102
|
+
variables: Variables,
|
|
103
|
+
evaluate: () => EvaluationResult<T>,
|
|
104
|
+
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
105
|
+
): [T /* Answer */, ?DataID /* Seen record */] {
|
|
106
|
+
const recordSource = this._getRecordSource();
|
|
107
|
+
const recordID = RelayModernRecord.getDataID(record);
|
|
108
|
+
|
|
109
|
+
const storageKey = getStorageKey(field, variables);
|
|
110
|
+
let linkedID = RelayModernRecord.getLinkedRecordID(record, storageKey);
|
|
111
|
+
let linkedRecord = linkedID == null ? null : recordSource.get(linkedID);
|
|
112
|
+
if (
|
|
113
|
+
linkedRecord == null ||
|
|
114
|
+
this._isInvalid(linkedRecord, getDataForResolverFragment)
|
|
115
|
+
) {
|
|
116
|
+
// Cache miss; evaluate the selector and store the result in a new record:
|
|
117
|
+
linkedID = linkedID ?? generateClientID(recordID, storageKey);
|
|
118
|
+
linkedRecord = RelayModernRecord.create(linkedID, '__RELAY_RESOLVER__');
|
|
119
|
+
|
|
120
|
+
const evaluationResult = evaluate();
|
|
121
|
+
RelayModernRecord.setValue(
|
|
122
|
+
linkedRecord,
|
|
123
|
+
RELAY_RESOLVER_VALUE_KEY,
|
|
124
|
+
evaluationResult.resolverResult,
|
|
125
|
+
);
|
|
126
|
+
RelayModernRecord.setValue(
|
|
127
|
+
linkedRecord,
|
|
128
|
+
RELAY_RESOLVER_INPUTS_KEY,
|
|
129
|
+
evaluationResult.fragmentValue,
|
|
130
|
+
);
|
|
131
|
+
RelayModernRecord.setValue(
|
|
132
|
+
linkedRecord,
|
|
133
|
+
RELAY_RESOLVER_READER_SELECTOR_KEY,
|
|
134
|
+
evaluationResult.readerSelector,
|
|
135
|
+
);
|
|
136
|
+
recordSource.set(linkedID, linkedRecord);
|
|
137
|
+
|
|
138
|
+
// Link the resolver value record to the resolver field of the record being read:
|
|
139
|
+
const nextRecord = RelayModernRecord.clone(record);
|
|
140
|
+
RelayModernRecord.setLinkedRecordID(nextRecord, storageKey, linkedID);
|
|
141
|
+
recordSource.set(RelayModernRecord.getDataID(nextRecord), nextRecord);
|
|
142
|
+
|
|
143
|
+
// Put records observed by the resolver into the dependency graph:
|
|
144
|
+
const resolverID = evaluationResult.resolverID;
|
|
145
|
+
addDependencyEdge(this._resolverIDToRecordIDs, resolverID, linkedID);
|
|
146
|
+
addDependencyEdge(this._recordIDToResolverIDs, recordID, resolverID);
|
|
147
|
+
for (const seenRecordID of evaluationResult.seenRecordIDs) {
|
|
148
|
+
addDependencyEdge(
|
|
149
|
+
this._recordIDToResolverIDs,
|
|
150
|
+
seenRecordID,
|
|
151
|
+
resolverID,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// $FlowFixMe[incompatible-type] - will always be empty
|
|
157
|
+
const answer: T = linkedRecord[RELAY_RESOLVER_VALUE_KEY];
|
|
158
|
+
return [answer, linkedID];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
invalidateDataIDs(
|
|
162
|
+
updatedDataIDs: Set<DataID>, // Mutated in place
|
|
163
|
+
): void {
|
|
164
|
+
const recordSource = this._getRecordSource();
|
|
165
|
+
const visited: Set<string> = new Set();
|
|
166
|
+
const recordsToVisit = Array.from(updatedDataIDs);
|
|
167
|
+
while (recordsToVisit.length) {
|
|
168
|
+
const recordID = recordsToVisit.pop();
|
|
169
|
+
updatedDataIDs.add(recordID);
|
|
170
|
+
for (const fragment of this._recordIDToResolverIDs.get(recordID) ??
|
|
171
|
+
emptySet) {
|
|
172
|
+
if (!visited.has(fragment)) {
|
|
173
|
+
for (const anotherRecordID of this._resolverIDToRecordIDs.get(
|
|
174
|
+
fragment,
|
|
175
|
+
) ?? emptySet) {
|
|
176
|
+
this._markInvalidatedResolverRecord(
|
|
177
|
+
anotherRecordID,
|
|
178
|
+
recordSource,
|
|
179
|
+
updatedDataIDs,
|
|
180
|
+
);
|
|
181
|
+
if (!visited.has(anotherRecordID)) {
|
|
182
|
+
recordsToVisit.push(anotherRecordID);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
_markInvalidatedResolverRecord(
|
|
191
|
+
dataID: DataID,
|
|
192
|
+
recordSource: MutableRecordSource, // Written to
|
|
193
|
+
updatedDataIDs: Set<DataID>, // Mutated in place
|
|
194
|
+
) {
|
|
195
|
+
const record = recordSource.get(dataID);
|
|
196
|
+
if (!record) {
|
|
197
|
+
warning(
|
|
198
|
+
false,
|
|
199
|
+
'Expected a resolver record with ID %s, but it was missing.',
|
|
200
|
+
dataID,
|
|
201
|
+
);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const nextRecord = RelayModernRecord.clone(record);
|
|
205
|
+
RelayModernRecord.setValue(
|
|
206
|
+
nextRecord,
|
|
207
|
+
RELAY_RESOLVER_INVALIDATION_KEY,
|
|
208
|
+
true,
|
|
209
|
+
);
|
|
210
|
+
recordSource.set(dataID, nextRecord);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
_isInvalid(
|
|
214
|
+
record: Record,
|
|
215
|
+
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
216
|
+
): boolean {
|
|
217
|
+
if (!RelayModernRecord.getValue(record, RELAY_RESOLVER_INVALIDATION_KEY)) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
const originalInputs = RelayModernRecord.getValue(
|
|
221
|
+
record,
|
|
222
|
+
RELAY_RESOLVER_INPUTS_KEY,
|
|
223
|
+
);
|
|
224
|
+
// $FlowFixMe[incompatible-type] - storing values in records is not typed
|
|
225
|
+
const readerSelector: ?SingularReaderSelector = RelayModernRecord.getValue(
|
|
226
|
+
record,
|
|
227
|
+
RELAY_RESOLVER_READER_SELECTOR_KEY,
|
|
228
|
+
);
|
|
229
|
+
if (originalInputs == null || readerSelector == null) {
|
|
230
|
+
warning(
|
|
231
|
+
false,
|
|
232
|
+
'Expected previous inputs and reader selector on resolver record with ID %s, but they were missing.',
|
|
233
|
+
RelayModernRecord.getDataID(record),
|
|
234
|
+
);
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
const latestValues = getDataForResolverFragment(readerSelector);
|
|
238
|
+
const recycled = recycleNodesInto(originalInputs, latestValues);
|
|
239
|
+
if (recycled !== originalInputs) {
|
|
240
|
+
return true;
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
module.exports = {
|
|
247
|
+
NoopResolverCache,
|
|
248
|
+
RecordResolverCache,
|
|
249
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
* @flow strict-local
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// flowlint ambiguous-object-type:error
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
import type {GraphQLTaggedNode} from '../query/GraphQLTag';
|
|
16
|
+
import type {FragmentType, SingularReaderSelector} from './RelayStoreTypes';
|
|
17
|
+
|
|
18
|
+
const {getFragment} = require('../query/GraphQLTag');
|
|
19
|
+
const {getSelector} = require('./RelayModernSelector');
|
|
20
|
+
const invariant = require('invariant');
|
|
21
|
+
|
|
22
|
+
// When we call the user-supplied resolver function, it will in turn call
|
|
23
|
+
// `readFragment`, but that's a global function -- it needs information
|
|
24
|
+
// about what resolver is being executed, which is supplied by putting the
|
|
25
|
+
// info on this stack before we call the resolver function.
|
|
26
|
+
type ResolverContext = {|
|
|
27
|
+
getDataForResolverFragment: (SingularReaderSelector, FragmentType) => mixed,
|
|
28
|
+
|};
|
|
29
|
+
const contextStack: Array<ResolverContext> = [];
|
|
30
|
+
|
|
31
|
+
function withResolverContext<T>(context: ResolverContext, cb: () => T): T {
|
|
32
|
+
contextStack.push(context);
|
|
33
|
+
try {
|
|
34
|
+
return cb();
|
|
35
|
+
} finally {
|
|
36
|
+
contextStack.pop();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// NOTE: these declarations are copied from 'useFragment'; it would be good
|
|
41
|
+
// to figure out how to share the same type signature between the two functions.
|
|
42
|
+
// The declarations ensure that the type of the returned data is:
|
|
43
|
+
// - non-nullable if the provided ref type is non-nullable
|
|
44
|
+
// - nullable if the provided ref type is nullable
|
|
45
|
+
// - array of non-nullable if the privoided ref type is an array of
|
|
46
|
+
// non-nullable refs
|
|
47
|
+
// - array of nullable if the privoided ref type is an array of nullable refs
|
|
48
|
+
|
|
49
|
+
declare function readFragment<
|
|
50
|
+
TKey: {+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
|
|
51
|
+
>(
|
|
52
|
+
fragmentInput: GraphQLTaggedNode,
|
|
53
|
+
fragmentKey: TKey,
|
|
54
|
+
): $Call<<TFragmentData>({+$data?: TFragmentData, ...}) => TFragmentData, TKey>;
|
|
55
|
+
|
|
56
|
+
declare function readFragment<
|
|
57
|
+
TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
|
|
58
|
+
>(
|
|
59
|
+
fragmentInput: GraphQLTaggedNode,
|
|
60
|
+
fragmentKey: TKey,
|
|
61
|
+
): $Call<
|
|
62
|
+
<TFragmentData>(?{+$data?: TFragmentData, ...}) => ?TFragmentData,
|
|
63
|
+
TKey,
|
|
64
|
+
>;
|
|
65
|
+
|
|
66
|
+
declare function readFragment<
|
|
67
|
+
TKey: $ReadOnlyArray<{
|
|
68
|
+
+$data?: mixed,
|
|
69
|
+
+$fragmentSpreads: FragmentType,
|
|
70
|
+
...
|
|
71
|
+
}>,
|
|
72
|
+
>(
|
|
73
|
+
fragmentInput: GraphQLTaggedNode,
|
|
74
|
+
fragmentKey: TKey,
|
|
75
|
+
): $Call<
|
|
76
|
+
<TFragmentData>(
|
|
77
|
+
$ReadOnlyArray<{+$data?: TFragmentData, ...}>,
|
|
78
|
+
) => TFragmentData,
|
|
79
|
+
TKey,
|
|
80
|
+
>;
|
|
81
|
+
|
|
82
|
+
declare function readFragment<
|
|
83
|
+
TKey: ?$ReadOnlyArray<{
|
|
84
|
+
+$data?: mixed,
|
|
85
|
+
+$fragmentSpreads: FragmentType,
|
|
86
|
+
...
|
|
87
|
+
}>,
|
|
88
|
+
>(
|
|
89
|
+
fragmentInput: GraphQLTaggedNode,
|
|
90
|
+
fragmentKey: TKey,
|
|
91
|
+
): $Call<
|
|
92
|
+
<TFragmentData>(
|
|
93
|
+
?$ReadOnlyArray<{+$data?: TFragmentData, ...}>,
|
|
94
|
+
) => ?TFragmentData,
|
|
95
|
+
TKey,
|
|
96
|
+
>;
|
|
97
|
+
|
|
98
|
+
function readFragment(
|
|
99
|
+
fragmentInput: GraphQLTaggedNode,
|
|
100
|
+
fragmentKey: FragmentType,
|
|
101
|
+
): mixed {
|
|
102
|
+
if (!contextStack.length) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
'readFragment should be called only from within a Relay Resolver function.',
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const context = contextStack[contextStack.length - 1];
|
|
108
|
+
const fragmentNode = getFragment(fragmentInput);
|
|
109
|
+
const fragmentSelector = getSelector(fragmentNode, fragmentKey);
|
|
110
|
+
invariant(
|
|
111
|
+
fragmentSelector != null,
|
|
112
|
+
`Expected a selector for the fragment of the resolver ${fragmentNode.name}, but got null.`,
|
|
113
|
+
);
|
|
114
|
+
invariant(
|
|
115
|
+
fragmentSelector.kind === 'SingularReaderSelector',
|
|
116
|
+
`Expected a singular reader selector for the fragment of the resolver ${fragmentNode.name}, but it was plural.`,
|
|
117
|
+
);
|
|
118
|
+
return context.getDataForResolverFragment(fragmentSelector, fragmentKey);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {readFragment, withResolverContext};
|
|
@@ -56,7 +56,7 @@ if (__DEV__) {
|
|
|
56
56
|
const keyStyle = {style: 'rgb(136, 19, 145)'};
|
|
57
57
|
const nullStyle = {style: 'color: #777'};
|
|
58
58
|
|
|
59
|
-
const reference = (object, config) => {
|
|
59
|
+
const reference = (object, config: void) => {
|
|
60
60
|
return object == null
|
|
61
61
|
? ['span', nullStyle, 'undefined']
|
|
62
62
|
: ['object', {object, config}];
|
|
@@ -100,7 +100,7 @@ if (__DEV__) {
|
|
|
100
100
|
}
|
|
101
101
|
return renderRecordHeader(obj);
|
|
102
102
|
},
|
|
103
|
-
hasBody(obj) {
|
|
103
|
+
hasBody(obj: $FlowFixMe) {
|
|
104
104
|
return true;
|
|
105
105
|
},
|
|
106
106
|
body(obj) {
|
package/store/TypeID.js.flow
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
+
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
16
|
+
|
|
15
17
|
const {generateClientID} = require('./ClientID');
|
|
16
18
|
const {ROOT_ID} = require('./RelayStoreUtils');
|
|
17
19
|
|
|
18
|
-
import type {DataID} from 'relay-runtime/util/RelayRuntimeTypes';
|
|
19
|
-
|
|
20
20
|
const VIEWER_ID: DataID = generateClientID(ROOT_ID, 'viewer');
|
|
21
21
|
const VIEWER_TYPE = 'Viewer';
|
|
22
22
|
|
|
@@ -12,12 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const areEqual = require('areEqual');
|
|
16
|
-
const invariant = require('invariant');
|
|
17
|
-
|
|
18
|
-
const {LINKED_FIELD} = require('../util/RelayConcreteNode');
|
|
19
|
-
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
20
|
-
|
|
21
15
|
import type {
|
|
22
16
|
NormalizationLinkedField,
|
|
23
17
|
NormalizationSelection,
|
|
@@ -25,6 +19,11 @@ import type {
|
|
|
25
19
|
import type {NormalizationLinkedHandle} from '../util/NormalizationNode';
|
|
26
20
|
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
27
21
|
|
|
22
|
+
const {LINKED_FIELD} = require('../util/RelayConcreteNode');
|
|
23
|
+
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
24
|
+
const areEqual = require('areEqual');
|
|
25
|
+
const invariant = require('invariant');
|
|
26
|
+
|
|
28
27
|
/**
|
|
29
28
|
* @private
|
|
30
29
|
*
|
|
@@ -12,12 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const areEqual = require('areEqual');
|
|
16
|
-
const invariant = require('invariant');
|
|
17
|
-
|
|
18
|
-
const {SCALAR_FIELD} = require('../util/RelayConcreteNode');
|
|
19
|
-
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
20
|
-
|
|
21
15
|
import type {
|
|
22
16
|
NormalizationScalarField,
|
|
23
17
|
NormalizationSelection,
|
|
@@ -25,6 +19,11 @@ import type {
|
|
|
25
19
|
import type {NormalizationScalarHandle} from '../util/NormalizationNode';
|
|
26
20
|
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
27
21
|
|
|
22
|
+
const {SCALAR_FIELD} = require('../util/RelayConcreteNode');
|
|
23
|
+
const {getHandleStorageKey} = require('./RelayStoreUtils');
|
|
24
|
+
const areEqual = require('areEqual');
|
|
25
|
+
const invariant = require('invariant');
|
|
26
|
+
|
|
28
27
|
/**
|
|
29
28
|
* @private
|
|
30
29
|
*
|
|
@@ -12,10 +12,6 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const RelayModernFragmentSpecResolver = require('./RelayModernFragmentSpecResolver');
|
|
16
|
-
|
|
17
|
-
const warning = require('warning');
|
|
18
|
-
|
|
19
15
|
import type {
|
|
20
16
|
FragmentMap,
|
|
21
17
|
FragmentSpecResolver,
|
|
@@ -23,6 +19,9 @@ import type {
|
|
|
23
19
|
RelayContext,
|
|
24
20
|
} from './RelayStoreTypes';
|
|
25
21
|
|
|
22
|
+
const RelayModernFragmentSpecResolver = require('./RelayModernFragmentSpecResolver');
|
|
23
|
+
const warning = require('warning');
|
|
24
|
+
|
|
26
25
|
function createFragmentSpecResolver(
|
|
27
26
|
context: RelayContext,
|
|
28
27
|
containerName: string,
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const invariant = require('invariant');
|
|
16
|
-
|
|
17
15
|
import type {RelayContext} from './RelayStoreTypes.js';
|
|
18
16
|
import typeof {createContext} from 'react';
|
|
19
17
|
|
|
18
|
+
const invariant = require('invariant');
|
|
19
|
+
|
|
20
20
|
// Ideally, we'd just import the type of the react module, but this causes Flow
|
|
21
21
|
// problems.
|
|
22
22
|
type React = {
|
|
@@ -38,7 +38,7 @@ function createRelayContext(react: React): React$Context<RelayContext | null> {
|
|
|
38
38
|
}
|
|
39
39
|
invariant(
|
|
40
40
|
react === firstReact,
|
|
41
|
-
'[createRelayContext]: You passing a different instance of React',
|
|
41
|
+
'[createRelayContext]: You are passing a different instance of React',
|
|
42
42
|
react.version,
|
|
43
43
|
);
|
|
44
44
|
return relayContext;
|
|
@@ -12,19 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const RelayModernRecord = require('./RelayModernRecord');
|
|
16
|
-
const RelayRecordSource = require('./RelayRecordSource');
|
|
17
|
-
const RelayResponseNormalizer = require('./RelayResponseNormalizer');
|
|
18
|
-
|
|
19
|
-
const {ROOT_TYPE} = require('./RelayStoreUtils');
|
|
20
|
-
|
|
21
15
|
import type {PayloadData, PayloadError} from '../network/RelayNetworkTypes';
|
|
22
16
|
import type {NormalizationOptions} from './RelayResponseNormalizer';
|
|
23
17
|
import type {
|
|
24
|
-
RelayResponsePayload,
|
|
25
18
|
NormalizationSelector,
|
|
19
|
+
RelayResponsePayload,
|
|
26
20
|
} from './RelayStoreTypes';
|
|
27
21
|
|
|
22
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
23
|
+
const RelayRecordSource = require('./RelayRecordSource');
|
|
24
|
+
const RelayResponseNormalizer = require('./RelayResponseNormalizer');
|
|
25
|
+
const {ROOT_TYPE} = require('./RelayStoreUtils');
|
|
26
|
+
|
|
28
27
|
function normalizeRelayPayload(
|
|
29
28
|
selector: NormalizationSelector,
|
|
30
29
|
payload: PayloadData,
|
|
@@ -12,24 +12,23 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
import type {GraphQLTaggedNode} from '../query/GraphQLTag';
|
|
16
|
+
import type {FragmentType} from './RelayStoreTypes';
|
|
16
17
|
|
|
17
18
|
const {getInlineDataFragment} = require('../query/GraphQLTag');
|
|
18
19
|
const {FRAGMENTS_KEY} = require('./RelayStoreUtils');
|
|
19
|
-
|
|
20
|
-
import type {GraphQLTaggedNode} from '../query/GraphQLTag';
|
|
21
|
-
import type {FragmentReference} from './RelayStoreTypes';
|
|
20
|
+
const invariant = require('invariant');
|
|
22
21
|
|
|
23
22
|
/**
|
|
24
23
|
* Reads an @inline data fragment that was spread into the parent fragment.
|
|
25
24
|
*/
|
|
26
25
|
|
|
27
26
|
declare function readInlineData<
|
|
28
|
-
|
|
27
|
+
TFragmentType: FragmentType,
|
|
29
28
|
TData,
|
|
30
29
|
TKey: {
|
|
31
30
|
+$data?: TData,
|
|
32
|
-
+$
|
|
31
|
+
+$fragmentSpreads: TFragmentType,
|
|
33
32
|
...
|
|
34
33
|
},
|
|
35
34
|
>(
|
|
@@ -37,11 +36,11 @@ declare function readInlineData<
|
|
|
37
36
|
fragmentRef: TKey,
|
|
38
37
|
): TData;
|
|
39
38
|
declare function readInlineData<
|
|
40
|
-
|
|
39
|
+
TFragmentType: FragmentType,
|
|
41
40
|
TData,
|
|
42
41
|
TKey: ?{
|
|
43
42
|
+$data?: TData,
|
|
44
|
-
+$
|
|
43
|
+
+$fragmentSpreads: TFragmentType,
|
|
45
44
|
...
|
|
46
45
|
},
|
|
47
46
|
>(
|