relay-runtime 11.0.2 → 13.0.0-rc.2
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/README.md +67 -0
- package/handlers/RelayDefaultHandlerProvider.js.flow +3 -3
- package/handlers/connection/ConnectionHandler.js.flow +9 -18
- package/handlers/connection/ConnectionInterface.js.flow +1 -1
- package/handlers/connection/MutationHandlers.js.flow +8 -12
- package/index.js +1 -1
- package/index.js.flow +57 -35
- package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
- package/lib/handlers/connection/ConnectionHandler.js +13 -19
- package/lib/handlers/connection/ConnectionInterface.js +1 -1
- package/lib/handlers/connection/MutationHandlers.js +4 -7
- package/lib/index.js +59 -44
- package/lib/multi-actor-environment/ActorIdentifier.js +12 -2
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +64 -20
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +324 -61
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +1 -1
- package/lib/multi-actor-environment/index.js +6 -2
- package/lib/mutations/RelayDeclarativeMutationConfig.js +5 -2
- package/lib/mutations/RelayRecordProxy.js +4 -3
- package/lib/mutations/RelayRecordSourceMutator.js +4 -3
- package/lib/mutations/RelayRecordSourceProxy.js +13 -5
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +19 -6
- package/lib/mutations/applyOptimisticMutation.js +7 -7
- package/lib/mutations/commitLocalUpdate.js +1 -1
- package/lib/mutations/commitMutation.js +15 -11
- package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +242 -0
- package/lib/mutations/validateMutation.js +11 -6
- package/lib/network/ConvertToExecuteFunction.js +3 -2
- package/lib/network/RelayNetwork.js +4 -3
- package/lib/network/RelayNetworkTypes.js +1 -1
- package/lib/network/RelayObservable.js +1 -1
- package/lib/network/RelayQueryResponseCache.js +22 -6
- package/lib/network/wrapNetworkWithLogObserver.js +79 -0
- package/lib/query/GraphQLTag.js +3 -2
- package/lib/query/PreloadableQueryRegistry.js +1 -1
- package/lib/query/fetchQuery.js +7 -6
- package/lib/query/fetchQueryInternal.js +1 -1
- package/lib/query/fetchQuery_DEPRECATED.js +3 -2
- package/lib/store/ClientID.js +8 -2
- package/lib/store/DataChecker.js +124 -55
- package/lib/store/OperationExecutor.js +489 -215
- package/lib/store/RelayConcreteVariables.js +27 -9
- package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
- package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
- package/lib/store/RelayModernEnvironment.js +100 -120
- package/lib/store/RelayModernFragmentSpecResolver.js +53 -27
- package/lib/store/RelayModernOperationDescriptor.js +3 -2
- package/lib/store/RelayModernRecord.js +48 -13
- package/lib/store/RelayModernSelector.js +15 -9
- package/lib/store/RelayModernStore.js +56 -23
- package/lib/store/RelayOperationTracker.js +34 -24
- package/lib/store/RelayOptimisticRecordSource.js +1 -1
- package/lib/store/RelayPublishQueue.js +35 -11
- package/lib/store/RelayReader.js +257 -72
- package/lib/store/RelayRecordSource.js +88 -4
- package/lib/store/RelayRecordState.js +1 -1
- package/lib/store/RelayReferenceMarker.js +34 -22
- package/lib/store/RelayResponseNormalizer.js +172 -96
- package/lib/store/RelayStoreReactFlightUtils.js +5 -11
- package/lib/store/RelayStoreSubscriptions.js +15 -10
- package/lib/store/RelayStoreTypes.js +1 -1
- package/lib/store/RelayStoreUtils.js +13 -8
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +10 -6
- package/lib/store/StoreInspector.js +1 -1
- package/lib/store/TypeID.js +1 -1
- package/lib/store/ViewerPattern.js +1 -1
- package/lib/store/cloneRelayHandleSourceField.js +6 -5
- package/lib/store/cloneRelayScalarHandleSourceField.js +6 -5
- package/lib/store/createFragmentSpecResolver.js +1 -1
- package/lib/store/createRelayContext.js +5 -3
- package/lib/store/defaultGetDataID.js +1 -1
- package/lib/store/defaultRequiredFieldLogger.js +1 -1
- package/lib/store/hasOverlappingIDs.js +1 -1
- package/lib/store/isRelayModernEnvironment.js +1 -1
- package/lib/store/normalizeRelayPayload.js +1 -1
- package/lib/store/readInlineData.js +7 -3
- package/lib/subscription/requestSubscription.js +32 -34
- package/lib/util/JSResourceTypes.flow.js +1 -1
- package/lib/util/NormalizationNode.js +1 -1
- package/lib/util/ReaderNode.js +1 -1
- package/lib/util/RelayConcreteNode.js +3 -1
- package/lib/util/RelayDefaultHandleKey.js +1 -1
- package/lib/util/RelayError.js +1 -1
- package/lib/util/RelayFeatureFlags.js +10 -7
- package/lib/util/RelayProfiler.js +1 -1
- package/lib/util/RelayReplaySubject.js +22 -7
- package/lib/util/RelayRuntimeTypes.js +1 -7
- package/lib/util/StringInterner.js +71 -0
- package/lib/util/createPayloadFor3DField.js +1 -1
- package/lib/util/deepFreeze.js +1 -1
- package/lib/util/generateID.js +1 -1
- package/lib/util/getAllRootVariables.js +29 -0
- package/lib/util/getFragmentIdentifier.js +16 -8
- package/lib/util/getOperation.js +3 -2
- 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 +3 -3
- package/lib/util/getRequestIdentifier.js +3 -3
- package/lib/util/getValueAtPath.js +51 -0
- package/lib/util/isEmptyObject.js +2 -2
- package/lib/util/isPromise.js +1 -1
- package/lib/util/isScalarAndEqual.js +1 -1
- package/lib/util/recycleNodesInto.js +1 -1
- package/lib/util/registerEnvironmentWithDevTools.js +26 -0
- package/lib/util/reportMissingRequiredFields.js +1 -1
- package/lib/util/resolveImmediate.js +1 -1
- package/lib/util/stableCopy.js +1 -1
- package/lib/util/withDuration.js +31 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +18 -2
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +94 -58
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +366 -93
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +88 -23
- package/multi-actor-environment/index.js.flow +3 -1
- package/mutations/RelayDeclarativeMutationConfig.js.flow +33 -27
- package/mutations/RelayRecordProxy.js.flow +5 -6
- package/mutations/RelayRecordSourceMutator.js.flow +5 -7
- package/mutations/RelayRecordSourceProxy.js.flow +20 -11
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +23 -8
- package/mutations/applyOptimisticMutation.js.flow +14 -15
- package/mutations/commitLocalUpdate.js.flow +2 -2
- package/mutations/commitMutation.js.flow +36 -47
- package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +318 -0
- package/mutations/validateMutation.js.flow +27 -17
- package/network/ConvertToExecuteFunction.js.flow +3 -3
- package/network/RelayNetwork.js.flow +5 -6
- package/network/RelayNetworkTypes.js.flow +1 -1
- package/network/RelayObservable.js.flow +2 -2
- package/network/RelayQueryResponseCache.js.flow +35 -22
- package/network/wrapNetworkWithLogObserver.js.flow +99 -0
- package/package.json +2 -2
- package/query/GraphQLTag.js.flow +11 -11
- package/query/PreloadableQueryRegistry.js.flow +5 -3
- package/query/fetchQuery.js.flow +19 -19
- package/query/fetchQueryInternal.js.flow +7 -10
- package/query/fetchQuery_DEPRECATED.js.flow +7 -7
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +15 -4
- package/store/DataChecker.js.flow +142 -60
- package/store/OperationExecutor.js.flow +575 -320
- package/store/RelayConcreteVariables.js.flow +28 -9
- package/store/RelayExperimentalGraphResponseHandler.js.flow +121 -0
- package/store/RelayExperimentalGraphResponseTransform.js.flow +470 -0
- package/store/RelayModernEnvironment.js.flow +91 -115
- package/store/RelayModernFragmentSpecResolver.js.flow +56 -32
- package/store/RelayModernOperationDescriptor.js.flow +13 -8
- package/store/RelayModernRecord.js.flow +68 -12
- package/store/RelayModernSelector.js.flow +25 -15
- package/store/RelayModernStore.js.flow +67 -32
- package/store/RelayOperationTracker.js.flow +60 -44
- package/store/RelayOptimisticRecordSource.js.flow +3 -3
- package/store/RelayPublishQueue.js.flow +74 -32
- package/store/RelayReader.js.flow +319 -100
- package/store/RelayRecordSource.js.flow +73 -7
- package/store/RelayRecordState.js.flow +1 -1
- package/store/RelayReferenceMarker.js.flow +41 -27
- package/store/RelayResponseNormalizer.js.flow +204 -86
- package/store/RelayStoreReactFlightUtils.js.flow +5 -12
- package/store/RelayStoreSubscriptions.js.flow +20 -12
- package/store/RelayStoreTypes.js.flow +200 -41
- package/store/RelayStoreUtils.js.flow +25 -12
- package/store/ResolverCache.js.flow +249 -0
- package/store/ResolverFragments.js.flow +16 -20
- package/store/StoreInspector.js.flow +3 -3
- package/store/TypeID.js.flow +2 -2
- package/store/ViewerPattern.js.flow +3 -3
- package/store/cloneRelayHandleSourceField.js.flow +6 -7
- package/store/cloneRelayScalarHandleSourceField.js.flow +6 -7
- package/store/createFragmentSpecResolver.js.flow +4 -5
- package/store/createRelayContext.js.flow +4 -4
- package/store/defaultGetDataID.js.flow +1 -1
- package/store/defaultRequiredFieldLogger.js.flow +1 -1
- package/store/hasOverlappingIDs.js.flow +1 -1
- package/store/isRelayModernEnvironment.js.flow +1 -1
- package/store/normalizeRelayPayload.js.flow +7 -8
- package/store/readInlineData.js.flow +8 -9
- package/subscription/requestSubscription.js.flow +55 -51
- package/util/JSResourceTypes.flow.js.flow +1 -1
- package/util/NormalizationNode.js.flow +11 -4
- package/util/ReaderNode.js.flow +25 -2
- package/util/RelayConcreteNode.js.flow +5 -1
- package/util/RelayDefaultHandleKey.js.flow +1 -1
- package/util/RelayError.js.flow +1 -1
- package/util/RelayFeatureFlags.js.flow +23 -15
- package/util/RelayProfiler.js.flow +1 -1
- package/util/RelayReplaySubject.js.flow +10 -10
- package/util/RelayRuntimeTypes.js.flow +70 -3
- package/util/StringInterner.js.flow +69 -0
- package/util/createPayloadFor3DField.js.flow +4 -4
- package/util/deepFreeze.js.flow +1 -1
- package/util/generateID.js.flow +1 -1
- package/util/getAllRootVariables.js.flow +36 -0
- package/util/getFragmentIdentifier.js.flow +28 -16
- package/util/getOperation.js.flow +3 -3
- package/util/getPaginationMetadata.js.flow +69 -0
- package/util/getPaginationVariables.js.flow +108 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +76 -0
- package/util/getRelayHandleKey.js.flow +2 -3
- package/util/getRequestIdentifier.js.flow +4 -4
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +2 -1
- package/util/isPromise.js.flow +1 -1
- package/util/isScalarAndEqual.js.flow +1 -1
- package/util/recycleNodesInto.js.flow +1 -1
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/reportMissingRequiredFields.js.flow +1 -1
- package/util/resolveImmediate.js.flow +2 -2
- package/util/stableCopy.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) 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
|
+
*/
|
|
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
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -12,23 +12,19 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
import type {GraphQLTaggedNode} from '../query/GraphQLTag';
|
|
16
|
+
import type {FragmentType, SingularReaderSelector} from './RelayStoreTypes';
|
|
16
17
|
|
|
17
18
|
const {getFragment} = require('../query/GraphQLTag');
|
|
18
19
|
const {getSelector} = require('./RelayModernSelector');
|
|
19
|
-
|
|
20
|
-
import type {GraphQLTaggedNode} from '../query/GraphQLTag';
|
|
21
|
-
import type {
|
|
22
|
-
FragmentReference,
|
|
23
|
-
SingularReaderSelector,
|
|
24
|
-
} from './RelayStoreTypes';
|
|
20
|
+
const invariant = require('invariant');
|
|
25
21
|
|
|
26
22
|
// When we call the user-supplied resolver function, it will in turn call
|
|
27
23
|
// `readFragment`, but that's a global function -- it needs information
|
|
28
24
|
// about what resolver is being executed, which is supplied by putting the
|
|
29
25
|
// info on this stack before we call the resolver function.
|
|
30
26
|
type ResolverContext = {|
|
|
31
|
-
getDataForResolverFragment: SingularReaderSelector => mixed,
|
|
27
|
+
getDataForResolverFragment: (SingularReaderSelector, FragmentType) => mixed,
|
|
32
28
|
|};
|
|
33
29
|
const contextStack: Array<ResolverContext> = [];
|
|
34
30
|
|
|
@@ -51,17 +47,17 @@ function withResolverContext<T>(context: ResolverContext, cb: () => T): T {
|
|
|
51
47
|
// - array of nullable if the privoided ref type is an array of nullable refs
|
|
52
48
|
|
|
53
49
|
declare function readFragment<
|
|
54
|
-
TKey: {+$data?: mixed, +$
|
|
50
|
+
TKey: {+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
|
|
55
51
|
>(
|
|
56
52
|
fragmentInput: GraphQLTaggedNode,
|
|
57
|
-
|
|
53
|
+
fragmentKey: TKey,
|
|
58
54
|
): $Call<<TFragmentData>({+$data?: TFragmentData, ...}) => TFragmentData, TKey>;
|
|
59
55
|
|
|
60
56
|
declare function readFragment<
|
|
61
|
-
TKey: ?{+$data?: mixed, +$
|
|
57
|
+
TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
|
|
62
58
|
>(
|
|
63
59
|
fragmentInput: GraphQLTaggedNode,
|
|
64
|
-
|
|
60
|
+
fragmentKey: TKey,
|
|
65
61
|
): $Call<
|
|
66
62
|
<TFragmentData>(?{+$data?: TFragmentData, ...}) => ?TFragmentData,
|
|
67
63
|
TKey,
|
|
@@ -70,12 +66,12 @@ declare function readFragment<
|
|
|
70
66
|
declare function readFragment<
|
|
71
67
|
TKey: $ReadOnlyArray<{
|
|
72
68
|
+$data?: mixed,
|
|
73
|
-
+$
|
|
69
|
+
+$fragmentSpreads: FragmentType,
|
|
74
70
|
...
|
|
75
71
|
}>,
|
|
76
72
|
>(
|
|
77
73
|
fragmentInput: GraphQLTaggedNode,
|
|
78
|
-
|
|
74
|
+
fragmentKey: TKey,
|
|
79
75
|
): $Call<
|
|
80
76
|
<TFragmentData>(
|
|
81
77
|
$ReadOnlyArray<{+$data?: TFragmentData, ...}>,
|
|
@@ -86,12 +82,12 @@ declare function readFragment<
|
|
|
86
82
|
declare function readFragment<
|
|
87
83
|
TKey: ?$ReadOnlyArray<{
|
|
88
84
|
+$data?: mixed,
|
|
89
|
-
+$
|
|
85
|
+
+$fragmentSpreads: FragmentType,
|
|
90
86
|
...
|
|
91
87
|
}>,
|
|
92
88
|
>(
|
|
93
89
|
fragmentInput: GraphQLTaggedNode,
|
|
94
|
-
|
|
90
|
+
fragmentKey: TKey,
|
|
95
91
|
): $Call<
|
|
96
92
|
<TFragmentData>(
|
|
97
93
|
?$ReadOnlyArray<{+$data?: TFragmentData, ...}>,
|
|
@@ -101,7 +97,7 @@ declare function readFragment<
|
|
|
101
97
|
|
|
102
98
|
function readFragment(
|
|
103
99
|
fragmentInput: GraphQLTaggedNode,
|
|
104
|
-
|
|
100
|
+
fragmentKey: FragmentType,
|
|
105
101
|
): mixed {
|
|
106
102
|
if (!contextStack.length) {
|
|
107
103
|
throw new Error(
|
|
@@ -110,7 +106,7 @@ function readFragment(
|
|
|
110
106
|
}
|
|
111
107
|
const context = contextStack[contextStack.length - 1];
|
|
112
108
|
const fragmentNode = getFragment(fragmentInput);
|
|
113
|
-
const fragmentSelector = getSelector(fragmentNode,
|
|
109
|
+
const fragmentSelector = getSelector(fragmentNode, fragmentKey);
|
|
114
110
|
invariant(
|
|
115
111
|
fragmentSelector != null,
|
|
116
112
|
`Expected a selector for the fragment of the resolver ${fragmentNode.name}, but got null.`,
|
|
@@ -119,7 +115,7 @@ function readFragment(
|
|
|
119
115
|
fragmentSelector.kind === 'SingularReaderSelector',
|
|
120
116
|
`Expected a singular reader selector for the fragment of the resolver ${fragmentNode.name}, but it was plural.`,
|
|
121
117
|
);
|
|
122
|
-
return context.getDataForResolverFragment(fragmentSelector);
|
|
118
|
+
return context.getDataForResolverFragment(fragmentSelector, fragmentKey);
|
|
123
119
|
}
|
|
124
120
|
|
|
125
121
|
module.exports = {readFragment, withResolverContext};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*
|
|
7
|
-
* @flow strict
|
|
7
|
+
* @flow strict-local
|
|
8
8
|
* @format
|
|
9
9
|
*/
|
|
10
10
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
@@ -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
|
>(
|