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
|
@@ -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,17 +12,41 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
16
|
+
import type {PayloadData} from '../network/RelayNetworkTypes';
|
|
17
|
+
import type {
|
|
18
|
+
NormalizationActorChange,
|
|
19
|
+
NormalizationDefer,
|
|
20
|
+
NormalizationFlightField,
|
|
21
|
+
NormalizationLinkedField,
|
|
22
|
+
NormalizationModuleImport,
|
|
23
|
+
NormalizationNode,
|
|
24
|
+
NormalizationScalarField,
|
|
25
|
+
NormalizationStream,
|
|
26
|
+
} from '../util/NormalizationNode';
|
|
27
|
+
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
28
|
+
import type {
|
|
29
|
+
FollowupPayload,
|
|
30
|
+
HandleFieldPayload,
|
|
31
|
+
IncrementalDataPlaceholder,
|
|
32
|
+
MutableRecordSource,
|
|
33
|
+
NormalizationSelector,
|
|
34
|
+
ReactFlightPayloadDeserializer,
|
|
35
|
+
ReactFlightReachableExecutableDefinitions,
|
|
36
|
+
ReactFlightServerErrorHandler,
|
|
37
|
+
Record,
|
|
38
|
+
RelayResponsePayload,
|
|
39
|
+
} from './RelayStoreTypes';
|
|
21
40
|
|
|
22
41
|
const {
|
|
23
|
-
|
|
42
|
+
ACTOR_IDENTIFIER_FIELD_NAME,
|
|
43
|
+
getActorIdentifierFromPayload,
|
|
44
|
+
} = require('../multi-actor-environment/ActorUtils');
|
|
45
|
+
const {
|
|
46
|
+
ACTOR_CHANGE,
|
|
24
47
|
CLIENT_COMPONENT,
|
|
25
48
|
CLIENT_EXTENSION,
|
|
49
|
+
CONDITION,
|
|
26
50
|
DEFER,
|
|
27
51
|
FLIGHT_FIELD,
|
|
28
52
|
FRAGMENT_SPREAD,
|
|
@@ -35,49 +59,31 @@ const {
|
|
|
35
59
|
STREAM,
|
|
36
60
|
TYPE_DISCRIMINATOR,
|
|
37
61
|
} = require('../util/RelayConcreteNode');
|
|
62
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
38
63
|
const {generateClientID, isClientID} = require('./ClientID');
|
|
64
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
65
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
39
66
|
const {createNormalizationSelector} = require('./RelayModernSelector');
|
|
40
67
|
const {
|
|
41
|
-
refineToReactFlightPayloadData,
|
|
42
68
|
REACT_FLIGHT_EXECUTABLE_DEFINITIONS_STORAGE_KEY,
|
|
43
69
|
REACT_FLIGHT_TREE_STORAGE_KEY,
|
|
44
70
|
REACT_FLIGHT_TYPE_NAME,
|
|
71
|
+
refineToReactFlightPayloadData,
|
|
45
72
|
} = require('./RelayStoreReactFlightUtils');
|
|
46
73
|
const {
|
|
74
|
+
ROOT_ID,
|
|
75
|
+
ROOT_TYPE,
|
|
76
|
+
TYPENAME_KEY,
|
|
47
77
|
getArgumentValues,
|
|
48
78
|
getHandleStorageKey,
|
|
49
79
|
getModuleComponentKey,
|
|
50
80
|
getModuleOperationKey,
|
|
51
81
|
getStorageKey,
|
|
52
|
-
TYPENAME_KEY,
|
|
53
|
-
ROOT_ID,
|
|
54
|
-
ROOT_TYPE,
|
|
55
82
|
} = require('./RelayStoreUtils');
|
|
56
|
-
const {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
NormalizationDefer,
|
|
61
|
-
NormalizationFlightField,
|
|
62
|
-
NormalizationLinkedField,
|
|
63
|
-
NormalizationModuleImport,
|
|
64
|
-
NormalizationNode,
|
|
65
|
-
NormalizationScalarField,
|
|
66
|
-
NormalizationStream,
|
|
67
|
-
} from '../util/NormalizationNode';
|
|
68
|
-
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
69
|
-
import type {
|
|
70
|
-
HandleFieldPayload,
|
|
71
|
-
IncrementalDataPlaceholder,
|
|
72
|
-
ModuleImportPayload,
|
|
73
|
-
MutableRecordSource,
|
|
74
|
-
NormalizationSelector,
|
|
75
|
-
ReactFlightReachableExecutableDefinitions,
|
|
76
|
-
ReactFlightPayloadDeserializer,
|
|
77
|
-
ReactFlightServerErrorHandler,
|
|
78
|
-
Record,
|
|
79
|
-
RelayResponsePayload,
|
|
80
|
-
} from './RelayStoreTypes';
|
|
83
|
+
const {TYPE_SCHEMA_TYPE, generateTypeID} = require('./TypeID');
|
|
84
|
+
const areEqual = require('areEqual');
|
|
85
|
+
const invariant = require('invariant');
|
|
86
|
+
const warning = require('warning');
|
|
81
87
|
|
|
82
88
|
export type GetDataID = (
|
|
83
89
|
fieldValue: interface {[string]: mixed},
|
|
@@ -91,6 +97,7 @@ export type NormalizationOptions = {|
|
|
|
91
97
|
+reactFlightPayloadDeserializer?: ?ReactFlightPayloadDeserializer,
|
|
92
98
|
+reactFlightServerErrorHandler?: ?ReactFlightServerErrorHandler,
|
|
93
99
|
+shouldProcessClientComponents?: ?boolean,
|
|
100
|
+
+actorIdentifier?: ?ActorIdentifier,
|
|
94
101
|
|};
|
|
95
102
|
|
|
96
103
|
/**
|
|
@@ -118,13 +125,14 @@ function normalize(
|
|
|
118
125
|
* Helper for handling payloads.
|
|
119
126
|
*/
|
|
120
127
|
class RelayResponseNormalizer {
|
|
128
|
+
_actorIdentifier: ?ActorIdentifier;
|
|
121
129
|
_getDataId: GetDataID;
|
|
122
130
|
_handleFieldPayloads: Array<HandleFieldPayload>;
|
|
123
131
|
_treatMissingFieldsAsNull: boolean;
|
|
124
132
|
_incrementalPlaceholders: Array<IncrementalDataPlaceholder>;
|
|
125
133
|
_isClientExtension: boolean;
|
|
126
134
|
_isUnmatchedAbstractType: boolean;
|
|
127
|
-
|
|
135
|
+
_followupPayloads: Array<FollowupPayload>;
|
|
128
136
|
_path: Array<string>;
|
|
129
137
|
_recordSource: MutableRecordSource;
|
|
130
138
|
_variables: Variables;
|
|
@@ -137,13 +145,14 @@ class RelayResponseNormalizer {
|
|
|
137
145
|
variables: Variables,
|
|
138
146
|
options: NormalizationOptions,
|
|
139
147
|
) {
|
|
148
|
+
this._actorIdentifier = options.actorIdentifier;
|
|
140
149
|
this._getDataId = options.getDataID;
|
|
141
150
|
this._handleFieldPayloads = [];
|
|
142
151
|
this._treatMissingFieldsAsNull = options.treatMissingFieldsAsNull;
|
|
143
152
|
this._incrementalPlaceholders = [];
|
|
144
153
|
this._isClientExtension = false;
|
|
145
154
|
this._isUnmatchedAbstractType = false;
|
|
146
|
-
this.
|
|
155
|
+
this._followupPayloads = [];
|
|
147
156
|
this._path = options.path ? [...options.path] : [];
|
|
148
157
|
this._recordSource = recordSource;
|
|
149
158
|
this._variables = variables;
|
|
@@ -169,7 +178,7 @@ class RelayResponseNormalizer {
|
|
|
169
178
|
errors: null,
|
|
170
179
|
fieldPayloads: this._handleFieldPayloads,
|
|
171
180
|
incrementalPlaceholders: this._incrementalPlaceholders,
|
|
172
|
-
|
|
181
|
+
followupPayloads: this._followupPayloads,
|
|
173
182
|
source: this._recordSource,
|
|
174
183
|
isFinal: false,
|
|
175
184
|
};
|
|
@@ -181,7 +190,6 @@ class RelayResponseNormalizer {
|
|
|
181
190
|
'RelayResponseNormalizer(): Undefined variable `%s`.',
|
|
182
191
|
name,
|
|
183
192
|
);
|
|
184
|
-
// $FlowFixMe[cannot-write]
|
|
185
193
|
return this._variables[name];
|
|
186
194
|
}
|
|
187
195
|
|
|
@@ -208,13 +216,22 @@ class RelayResponseNormalizer {
|
|
|
208
216
|
this._normalizeField(node, selection, record, data);
|
|
209
217
|
break;
|
|
210
218
|
case CONDITION:
|
|
211
|
-
const conditionValue =
|
|
219
|
+
const conditionValue = Boolean(
|
|
220
|
+
this._getVariableValue(selection.condition),
|
|
221
|
+
);
|
|
212
222
|
if (conditionValue === selection.passingValue) {
|
|
213
223
|
this._traverseSelections(selection, record, data);
|
|
214
224
|
}
|
|
215
225
|
break;
|
|
216
226
|
case FRAGMENT_SPREAD: {
|
|
227
|
+
const prevVariables = this._variables;
|
|
228
|
+
this._variables = getLocalVariables(
|
|
229
|
+
this._variables,
|
|
230
|
+
selection.fragment.argumentDefinitions,
|
|
231
|
+
selection.args,
|
|
232
|
+
);
|
|
217
233
|
this._traverseSelections(selection.fragment, record, data);
|
|
234
|
+
this._variables = prevVariables;
|
|
218
235
|
break;
|
|
219
236
|
}
|
|
220
237
|
case INLINE_FRAGMENT: {
|
|
@@ -224,7 +241,7 @@ class RelayResponseNormalizer {
|
|
|
224
241
|
if (typeName === selection.type) {
|
|
225
242
|
this._traverseSelections(selection, record, data);
|
|
226
243
|
}
|
|
227
|
-
} else
|
|
244
|
+
} else {
|
|
228
245
|
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
229
246
|
const typeName = RelayModernRecord.getType(record);
|
|
230
247
|
const typeID = generateTypeID(typeName);
|
|
@@ -241,36 +258,24 @@ class RelayResponseNormalizer {
|
|
|
241
258
|
if (implementsInterface) {
|
|
242
259
|
this._traverseSelections(selection, record, data);
|
|
243
260
|
}
|
|
244
|
-
} else {
|
|
245
|
-
// legacy behavior for abstract refinements: always normalize even
|
|
246
|
-
// if the type doesn't conform, but track if the type matches or not
|
|
247
|
-
// for determining whether response fields are expected to be present
|
|
248
|
-
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
249
|
-
const parentIsUnmatchedAbstractType = this._isUnmatchedAbstractType;
|
|
250
|
-
this._isUnmatchedAbstractType =
|
|
251
|
-
this._isUnmatchedAbstractType || !implementsInterface;
|
|
252
|
-
this._traverseSelections(selection, record, data);
|
|
253
|
-
this._isUnmatchedAbstractType = parentIsUnmatchedAbstractType;
|
|
254
261
|
}
|
|
255
262
|
break;
|
|
256
263
|
}
|
|
257
264
|
case TYPE_DISCRIMINATOR: {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
this._recordSource.set(typeID, typeRecord);
|
|
267
|
-
}
|
|
268
|
-
RelayModernRecord.setValue(
|
|
269
|
-
typeRecord,
|
|
270
|
-
abstractKey,
|
|
271
|
-
implementsInterface,
|
|
272
|
-
);
|
|
265
|
+
const {abstractKey} = selection;
|
|
266
|
+
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
267
|
+
const typeName = RelayModernRecord.getType(record);
|
|
268
|
+
const typeID = generateTypeID(typeName);
|
|
269
|
+
let typeRecord = this._recordSource.get(typeID);
|
|
270
|
+
if (typeRecord == null) {
|
|
271
|
+
typeRecord = RelayModernRecord.create(typeID, TYPE_SCHEMA_TYPE);
|
|
272
|
+
this._recordSource.set(typeID, typeRecord);
|
|
273
273
|
}
|
|
274
|
+
RelayModernRecord.setValue(
|
|
275
|
+
typeRecord,
|
|
276
|
+
abstractKey,
|
|
277
|
+
implementsInterface,
|
|
278
|
+
);
|
|
274
279
|
break;
|
|
275
280
|
}
|
|
276
281
|
case LINKED_HANDLE:
|
|
@@ -281,13 +286,17 @@ class RelayResponseNormalizer {
|
|
|
281
286
|
const fieldKey = getStorageKey(selection, this._variables);
|
|
282
287
|
const handleKey = getHandleStorageKey(selection, this._variables);
|
|
283
288
|
this._handleFieldPayloads.push({
|
|
289
|
+
/* $FlowFixMe[class-object-subtyping] added when improving typing
|
|
290
|
+
* for this parameters */
|
|
284
291
|
args,
|
|
285
292
|
dataID: RelayModernRecord.getDataID(record),
|
|
286
293
|
fieldKey,
|
|
287
294
|
handle: selection.handle,
|
|
288
295
|
handleKey,
|
|
289
296
|
handleArgs: selection.handleArgs
|
|
290
|
-
?
|
|
297
|
+
? /* $FlowFixMe[class-object-subtyping] added when improving typing
|
|
298
|
+
* for this parameters */
|
|
299
|
+
getArgumentValues(selection.handleArgs, this._variables)
|
|
291
300
|
: {},
|
|
292
301
|
});
|
|
293
302
|
break;
|
|
@@ -319,6 +328,9 @@ class RelayResponseNormalizer {
|
|
|
319
328
|
throw new Error('Flight fields are not yet supported.');
|
|
320
329
|
}
|
|
321
330
|
break;
|
|
331
|
+
case ACTOR_CHANGE:
|
|
332
|
+
this._normalizeActorChange(node, selection, record, data);
|
|
333
|
+
break;
|
|
322
334
|
default:
|
|
323
335
|
(selection: empty);
|
|
324
336
|
invariant(
|
|
@@ -362,6 +374,7 @@ class RelayResponseNormalizer {
|
|
|
362
374
|
this._variables,
|
|
363
375
|
),
|
|
364
376
|
typeName: RelayModernRecord.getType(record),
|
|
377
|
+
actorIdentifier: this._actorIdentifier,
|
|
365
378
|
});
|
|
366
379
|
}
|
|
367
380
|
}
|
|
@@ -394,6 +407,7 @@ class RelayResponseNormalizer {
|
|
|
394
407
|
parentID: RelayModernRecord.getDataID(record),
|
|
395
408
|
node: stream,
|
|
396
409
|
variables: this._variables,
|
|
410
|
+
actorIdentifier: this._actorIdentifier,
|
|
397
411
|
});
|
|
398
412
|
}
|
|
399
413
|
}
|
|
@@ -424,13 +438,16 @@ class RelayResponseNormalizer {
|
|
|
424
438
|
operationReference ?? null,
|
|
425
439
|
);
|
|
426
440
|
if (operationReference != null) {
|
|
427
|
-
this.
|
|
441
|
+
this._followupPayloads.push({
|
|
442
|
+
kind: 'ModuleImportPayload',
|
|
443
|
+
args: moduleImport.args,
|
|
428
444
|
data,
|
|
429
445
|
dataID: RelayModernRecord.getDataID(record),
|
|
430
446
|
operationReference,
|
|
431
447
|
path: [...this._path],
|
|
432
448
|
typeName,
|
|
433
449
|
variables: this._variables,
|
|
450
|
+
actorIdentifier: this._actorIdentifier,
|
|
434
451
|
});
|
|
435
452
|
}
|
|
436
453
|
}
|
|
@@ -488,7 +505,11 @@ class RelayResponseNormalizer {
|
|
|
488
505
|
this._validateConflictingFieldsWithIdenticalId(
|
|
489
506
|
record,
|
|
490
507
|
storageKey,
|
|
491
|
-
|
|
508
|
+
// When using `treatMissingFieldsAsNull` the conflicting validation raises a false positive
|
|
509
|
+
// because the value is set using `null` but validated using `fieldValue` which at this point
|
|
510
|
+
// will be `undefined`.
|
|
511
|
+
// Setting this to `null` matches the value that we actually set to the `fieldValue`.
|
|
512
|
+
null,
|
|
492
513
|
);
|
|
493
514
|
}
|
|
494
515
|
}
|
|
@@ -523,6 +544,99 @@ class RelayResponseNormalizer {
|
|
|
523
544
|
}
|
|
524
545
|
}
|
|
525
546
|
|
|
547
|
+
_normalizeActorChange(
|
|
548
|
+
parent: NormalizationNode,
|
|
549
|
+
selection: NormalizationActorChange,
|
|
550
|
+
record: Record,
|
|
551
|
+
data: PayloadData,
|
|
552
|
+
) {
|
|
553
|
+
const field = selection.linkedField;
|
|
554
|
+
invariant(
|
|
555
|
+
typeof data === 'object' && data,
|
|
556
|
+
'_normalizeActorChange(): Expected data for field `%s` to be an object.',
|
|
557
|
+
field.name,
|
|
558
|
+
);
|
|
559
|
+
const responseKey = field.alias || field.name;
|
|
560
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
561
|
+
const fieldValue = data[responseKey];
|
|
562
|
+
|
|
563
|
+
if (fieldValue == null) {
|
|
564
|
+
if (fieldValue === undefined) {
|
|
565
|
+
const isOptionalField =
|
|
566
|
+
this._isClientExtension || this._isUnmatchedAbstractType;
|
|
567
|
+
|
|
568
|
+
if (isOptionalField) {
|
|
569
|
+
return;
|
|
570
|
+
} else if (!this._treatMissingFieldsAsNull) {
|
|
571
|
+
if (__DEV__) {
|
|
572
|
+
warning(
|
|
573
|
+
false,
|
|
574
|
+
'RelayResponseNormalizer: Payload did not contain a value ' +
|
|
575
|
+
'for field `%s: %s`. Check that you are parsing with the same ' +
|
|
576
|
+
'query that was used to fetch the payload.',
|
|
577
|
+
responseKey,
|
|
578
|
+
storageKey,
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const actorIdentifier = getActorIdentifierFromPayload(fieldValue);
|
|
589
|
+
if (actorIdentifier == null) {
|
|
590
|
+
if (__DEV__) {
|
|
591
|
+
warning(
|
|
592
|
+
false,
|
|
593
|
+
'RelayResponseNormalizer: Payload did not contain a value ' +
|
|
594
|
+
'for field `%s`. Check that you are parsing with the same ' +
|
|
595
|
+
'query that was used to fetch the payload. Payload is `%s`.',
|
|
596
|
+
ACTOR_IDENTIFIER_FIELD_NAME,
|
|
597
|
+
JSON.stringify(fieldValue, null, 2),
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// $FlowFixMe[incompatible-call]
|
|
605
|
+
const typeName = field.concreteType ?? this._getRecordType(fieldValue);
|
|
606
|
+
const nextID =
|
|
607
|
+
this._getDataId(
|
|
608
|
+
// $FlowFixMe[incompatible-call]
|
|
609
|
+
fieldValue,
|
|
610
|
+
typeName,
|
|
611
|
+
) ||
|
|
612
|
+
RelayModernRecord.getLinkedRecordID(record, storageKey) ||
|
|
613
|
+
generateClientID(RelayModernRecord.getDataID(record), storageKey);
|
|
614
|
+
|
|
615
|
+
invariant(
|
|
616
|
+
typeof nextID === 'string',
|
|
617
|
+
'RelayResponseNormalizer: Expected id on field `%s` to be a string.',
|
|
618
|
+
storageKey,
|
|
619
|
+
);
|
|
620
|
+
|
|
621
|
+
RelayModernRecord.setActorLinkedRecordID(
|
|
622
|
+
record,
|
|
623
|
+
storageKey,
|
|
624
|
+
actorIdentifier,
|
|
625
|
+
nextID,
|
|
626
|
+
);
|
|
627
|
+
|
|
628
|
+
this._followupPayloads.push({
|
|
629
|
+
kind: 'ActorPayload',
|
|
630
|
+
data: (fieldValue: $FlowFixMe),
|
|
631
|
+
dataID: nextID,
|
|
632
|
+
path: [...this._path, responseKey],
|
|
633
|
+
typeName,
|
|
634
|
+
variables: this._variables,
|
|
635
|
+
node: field,
|
|
636
|
+
actorIdentifier,
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
|
|
526
640
|
_normalizeFlightField(
|
|
527
641
|
parent: NormalizationNode,
|
|
528
642
|
selection: NormalizationFlightField,
|
|
@@ -546,20 +660,17 @@ class RelayResponseNormalizer {
|
|
|
546
660
|
// Field not expected to exist regardless of whether the server is pruning null
|
|
547
661
|
// fields or not.
|
|
548
662
|
return;
|
|
549
|
-
} else
|
|
663
|
+
} else {
|
|
550
664
|
// Not optional and the server is not pruning null fields: field is expected
|
|
551
665
|
// to be present
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
'
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
return;
|
|
666
|
+
invariant(
|
|
667
|
+
this._treatMissingFieldsAsNull,
|
|
668
|
+
'RelayResponseNormalizer: Payload did not contain a value for ' +
|
|
669
|
+
'field `%s: %s`. Check that you are parsing with the same ' +
|
|
670
|
+
'query that was used to fetch the payload.',
|
|
671
|
+
responseKey,
|
|
672
|
+
storageKey,
|
|
673
|
+
);
|
|
563
674
|
}
|
|
564
675
|
}
|
|
565
676
|
RelayModernRecord.setValue(record, storageKey, null);
|
|
@@ -655,16 +766,20 @@ class RelayResponseNormalizer {
|
|
|
655
766
|
reactFlightClientResponse,
|
|
656
767
|
);
|
|
657
768
|
|
|
658
|
-
const reachableExecutableDefinitions: Array<ReactFlightReachableExecutableDefinitions> =
|
|
769
|
+
const reachableExecutableDefinitions: Array<ReactFlightReachableExecutableDefinitions> =
|
|
770
|
+
[];
|
|
659
771
|
for (const query of reactFlightPayload.queries) {
|
|
660
772
|
if (query.response.data != null) {
|
|
661
|
-
this.
|
|
773
|
+
this._followupPayloads.push({
|
|
774
|
+
kind: 'ModuleImportPayload',
|
|
775
|
+
args: null,
|
|
662
776
|
data: query.response.data,
|
|
663
777
|
dataID: ROOT_ID,
|
|
664
778
|
operationReference: query.module,
|
|
665
779
|
path: [],
|
|
666
780
|
typeName: ROOT_TYPE,
|
|
667
781
|
variables: query.variables,
|
|
782
|
+
actorIdentifier: this._actorIdentifier,
|
|
668
783
|
});
|
|
669
784
|
}
|
|
670
785
|
reachableExecutableDefinitions.push({
|
|
@@ -674,13 +789,16 @@ class RelayResponseNormalizer {
|
|
|
674
789
|
}
|
|
675
790
|
for (const fragment of reactFlightPayload.fragments) {
|
|
676
791
|
if (fragment.response.data != null) {
|
|
677
|
-
this.
|
|
792
|
+
this._followupPayloads.push({
|
|
793
|
+
kind: 'ModuleImportPayload',
|
|
794
|
+
args: null,
|
|
678
795
|
data: fragment.response.data,
|
|
679
796
|
dataID: fragment.__id,
|
|
680
797
|
operationReference: fragment.module,
|
|
681
798
|
path: [],
|
|
682
799
|
typeName: fragment.__typename,
|
|
683
800
|
variables: fragment.variables,
|
|
801
|
+
actorIdentifier: this._actorIdentifier,
|
|
684
802
|
});
|
|
685
803
|
}
|
|
686
804
|
reachableExecutableDefinitions.push({
|
|
@@ -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,13 +12,12 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const invariant = require('invariant');
|
|
16
|
-
|
|
17
|
-
const {getType} = require('./RelayModernRecord');
|
|
18
|
-
|
|
19
15
|
import type {ReactFlightPayloadData} from '../network/RelayNetworkTypes';
|
|
20
16
|
import type {ReactFlightClientResponse, Record} from './RelayStoreTypes';
|
|
21
17
|
|
|
18
|
+
const {getType} = require('./RelayModernRecord');
|
|
19
|
+
const invariant = require('invariant');
|
|
20
|
+
|
|
22
21
|
// Reachable (client) executable definitions encountered while server component
|
|
23
22
|
// rendering
|
|
24
23
|
const REACT_FLIGHT_EXECUTABLE_DEFINITIONS_STORAGE_KEY = 'executableDefinitions';
|
|
@@ -51,13 +50,7 @@ function getReactFlightClientResponse(
|
|
|
51
50
|
'got %s.',
|
|
52
51
|
record,
|
|
53
52
|
);
|
|
54
|
-
|
|
55
|
-
REACT_FLIGHT_TREE_STORAGE_KEY
|
|
56
|
-
]: $FlowFixMe);
|
|
57
|
-
if (response != null) {
|
|
58
|
-
return response;
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
53
|
+
return (record[REACT_FLIGHT_TREE_STORAGE_KEY]: $FlowFixMe);
|
|
61
54
|
}
|
|
62
55
|
|
|
63
56
|
module.exports = {
|
|
@@ -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,23 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
16
|
-
const RelayReader = require('./RelayReader');
|
|
17
|
-
|
|
18
|
-
const deepFreeze = require('../util/deepFreeze');
|
|
19
|
-
const hasOverlappingIDs = require('./hasOverlappingIDs');
|
|
20
|
-
const recycleNodesInto = require('../util/recycleNodesInto');
|
|
21
|
-
|
|
22
15
|
import type {Disposable} from '../util/RelayRuntimeTypes';
|
|
23
16
|
import type {
|
|
17
|
+
DataIDSet,
|
|
24
18
|
LogFunction,
|
|
25
19
|
OperationDescriptor,
|
|
26
|
-
DataIDSet,
|
|
27
20
|
RecordSource,
|
|
28
21
|
RequestDescriptor,
|
|
29
22
|
Snapshot,
|
|
30
23
|
StoreSubscriptions,
|
|
31
24
|
} from './RelayStoreTypes';
|
|
25
|
+
import type {ResolverCache} from './ResolverCache';
|
|
26
|
+
|
|
27
|
+
const deepFreeze = require('../util/deepFreeze');
|
|
28
|
+
const recycleNodesInto = require('../util/recycleNodesInto');
|
|
29
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
30
|
+
const hasOverlappingIDs = require('./hasOverlappingIDs');
|
|
31
|
+
const RelayReader = require('./RelayReader');
|
|
32
32
|
|
|
33
33
|
type Subscription = {|
|
|
34
34
|
callback: (snapshot: Snapshot) => void,
|
|
@@ -40,10 +40,12 @@ type Subscription = {|
|
|
|
40
40
|
class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
41
41
|
_subscriptions: Set<Subscription>;
|
|
42
42
|
__log: ?LogFunction;
|
|
43
|
+
_resolverCache: ResolverCache;
|
|
43
44
|
|
|
44
|
-
constructor(log?: ?LogFunction) {
|
|
45
|
+
constructor(log?: ?LogFunction, resolverCache: ResolverCache) {
|
|
45
46
|
this._subscriptions = new Set();
|
|
46
47
|
this.__log = log;
|
|
48
|
+
this._resolverCache = resolverCache;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
subscribe(
|
|
@@ -77,7 +79,11 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
77
79
|
return;
|
|
78
80
|
}
|
|
79
81
|
const snapshot = subscription.snapshot;
|
|
80
|
-
const backup = RelayReader.read(
|
|
82
|
+
const backup = RelayReader.read(
|
|
83
|
+
source,
|
|
84
|
+
snapshot.selector,
|
|
85
|
+
this._resolverCache,
|
|
86
|
+
);
|
|
81
87
|
const nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
82
88
|
(backup: $FlowFixMe).data = nextData; // backup owns the snapshot and can safely mutate
|
|
83
89
|
subscription.backup = backup;
|
|
@@ -95,6 +101,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
95
101
|
subscription.snapshot = {
|
|
96
102
|
data: subscription.snapshot.data,
|
|
97
103
|
isMissingData: backup.isMissingData,
|
|
104
|
+
missingClientEdges: backup.missingClientEdges,
|
|
98
105
|
seenRecords: backup.seenRecords,
|
|
99
106
|
selector: backup.selector,
|
|
100
107
|
missingRequiredFields: backup.missingRequiredFields,
|
|
@@ -150,12 +157,13 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
150
157
|
}
|
|
151
158
|
let nextSnapshot: Snapshot =
|
|
152
159
|
hasOverlappingUpdates || !backup
|
|
153
|
-
? RelayReader.read(source, snapshot.selector)
|
|
160
|
+
? RelayReader.read(source, snapshot.selector, this._resolverCache)
|
|
154
161
|
: backup;
|
|
155
162
|
const nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
|
|
156
163
|
nextSnapshot = ({
|
|
157
164
|
data: nextData,
|
|
158
165
|
isMissingData: nextSnapshot.isMissingData,
|
|
166
|
+
missingClientEdges: nextSnapshot.missingClientEdges,
|
|
159
167
|
seenRecords: nextSnapshot.seenRecords,
|
|
160
168
|
selector: nextSnapshot.selector,
|
|
161
169
|
missingRequiredFields: nextSnapshot.missingRequiredFields,
|