relay-runtime 12.0.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- 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 +2 -2
- package/index.js.flow +43 -34
- 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 +49 -46
- package/lib/multi-actor-environment/ActorIdentifier.js +1 -1
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +9 -5
- package/lib/multi-actor-environment/ActorUtils.js +1 -1
- package/lib/multi-actor-environment/MultiActorEnvironment.js +36 -23
- package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +1 -1
- package/lib/multi-actor-environment/index.js +3 -3
- 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 +13 -5
- package/lib/mutations/applyOptimisticMutation.js +7 -7
- package/lib/mutations/commitLocalUpdate.js +1 -1
- package/lib/mutations/commitMutation.js +16 -15
- package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +242 -0
- package/lib/mutations/validateMutation.js +7 -7
- 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 +2 -4
- package/lib/network/RelayQueryResponseCache.js +3 -3
- package/lib/network/wrapNetworkWithLogObserver.js +3 -2
- 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 +17 -18
- package/lib/store/OperationExecutor.js +14 -14
- package/lib/store/RelayConcreteVariables.js +7 -10
- package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
- package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
- package/lib/store/RelayModernEnvironment.js +67 -43
- package/lib/store/RelayModernFragmentSpecResolver.js +9 -9
- package/lib/store/RelayModernOperationDescriptor.js +3 -2
- package/lib/store/RelayModernRecord.js +13 -12
- package/lib/store/RelayModernSelector.js +15 -9
- package/lib/store/RelayModernStore.js +15 -16
- package/lib/store/RelayOperationTracker.js +1 -1
- package/lib/store/RelayOptimisticRecordSource.js +1 -1
- package/lib/store/RelayPublishQueue.js +12 -6
- package/lib/store/RelayReader.js +131 -40
- package/lib/store/RelayRecordSource.js +1 -1
- package/lib/store/RelayRecordState.js +1 -1
- package/lib/store/RelayReferenceMarker.js +11 -12
- package/lib/store/RelayResponseNormalizer.js +26 -23
- package/lib/store/RelayStoreReactFlightUtils.js +4 -4
- package/lib/store/RelayStoreSubscriptions.js +7 -5
- package/lib/store/RelayStoreTypes.js +1 -1
- package/lib/store/RelayStoreUtils.js +6 -6
- package/lib/store/ResolverCache.js +7 -7
- package/lib/store/ResolverFragments.js +12 -8
- 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 +4 -2
- 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 +4 -6
- 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 +2 -1
- package/lib/util/RelayDefaultHandleKey.js +1 -1
- package/lib/util/RelayError.js +1 -1
- package/lib/util/RelayFeatureFlags.js +8 -3
- package/lib/util/RelayProfiler.js +1 -1
- package/lib/util/RelayReplaySubject.js +1 -1
- 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 +1 -1
- package/lib/util/getPaginationVariables.js +3 -4
- package/lib/util/getPendingOperationsForFragment.js +1 -1
- package/lib/util/getRefetchMetadata.js +1 -1
- package/lib/util/getRelayHandleKey.js +3 -3
- package/lib/util/getRequestIdentifier.js +3 -3
- package/lib/util/getValueAtPath.js +1 -1
- package/lib/util/isEmptyObject.js +1 -1
- 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 +1 -1
- 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 +1 -1
- package/multi-actor-environment/ActorIdentifier.js.flow +1 -1
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +28 -20
- package/multi-actor-environment/ActorUtils.js.flow +3 -3
- package/multi-actor-environment/MultiActorEnvironment.js.flow +46 -25
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +28 -12
- package/multi-actor-environment/index.js.flow +2 -3
- package/mutations/RelayDeclarativeMutationConfig.js.flow +33 -28
- 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 +16 -6
- package/mutations/applyOptimisticMutation.js.flow +14 -15
- package/mutations/commitLocalUpdate.js.flow +2 -2
- package/mutations/commitMutation.js.flow +36 -49
- package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +318 -0
- package/mutations/validateMutation.js.flow +20 -18
- 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 -4
- package/network/RelayQueryResponseCache.js.flow +4 -4
- package/network/wrapNetworkWithLogObserver.js.flow +9 -9
- 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 +3 -3
- package/store/ClientID.js.flow +10 -3
- package/store/DataChecker.js.flow +21 -30
- package/store/OperationExecutor.js.flow +55 -63
- package/store/RelayConcreteVariables.js.flow +5 -11
- package/store/RelayExperimentalGraphResponseHandler.js.flow +121 -0
- package/store/RelayExperimentalGraphResponseTransform.js.flow +470 -0
- package/store/RelayModernEnvironment.js.flow +57 -28
- package/store/RelayModernFragmentSpecResolver.js.flow +18 -20
- package/store/RelayModernOperationDescriptor.js.flow +11 -12
- package/store/RelayModernRecord.js.flow +20 -13
- package/store/RelayModernSelector.js.flow +25 -15
- package/store/RelayModernStore.js.flow +22 -26
- package/store/RelayOperationTracker.js.flow +12 -18
- package/store/RelayOptimisticRecordSource.js.flow +3 -3
- package/store/RelayPublishQueue.js.flow +43 -24
- package/store/RelayReader.js.flow +181 -68
- package/store/RelayRecordSource.js.flow +3 -3
- package/store/RelayRecordState.js.flow +1 -1
- package/store/RelayReferenceMarker.js.flow +13 -16
- package/store/RelayResponseNormalizer.js.flow +44 -42
- package/store/RelayStoreReactFlightUtils.js.flow +4 -5
- package/store/RelayStoreSubscriptions.js.flow +10 -9
- package/store/RelayStoreTypes.js.flow +73 -30
- package/store/RelayStoreUtils.js.flow +9 -10
- package/store/ResolverCache.js.flow +17 -15
- package/store/ResolverFragments.js.flow +18 -25
- 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 +3 -3
- 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 +16 -25
- package/util/JSResourceTypes.flow.js.flow +1 -1
- package/util/NormalizationNode.js.flow +1 -1
- package/util/ReaderNode.js.flow +10 -1
- package/util/RelayConcreteNode.js.flow +4 -1
- package/util/RelayDefaultHandleKey.js.flow +1 -1
- package/util/RelayError.js.flow +1 -1
- package/util/RelayFeatureFlags.js.flow +15 -5
- package/util/RelayProfiler.js.flow +1 -1
- package/util/RelayReplaySubject.js.flow +3 -4
- 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 +6 -11
- package/util/getPaginationVariables.js.flow +6 -10
- package/util/getPendingOperationsForFragment.js.flow +3 -3
- package/util/getRefetchMetadata.js.flow +8 -12
- package/util/getRelayHandleKey.js.flow +2 -3
- package/util/getRequestIdentifier.js.flow +4 -4
- package/util/getValueAtPath.js.flow +1 -1
- package/util/isEmptyObject.js.flow +1 -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 +1 -1
- 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 +1 -1
package/store/ClientID.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
|
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
import type {DataID} from '../util/RelayRuntimeTypes';
|
|
16
16
|
|
|
17
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
18
|
+
const {intern} = require('../util/StringInterner');
|
|
19
|
+
|
|
17
20
|
const PREFIX = 'client:';
|
|
18
21
|
|
|
19
22
|
function generateClientID(
|
|
@@ -21,7 +24,11 @@ function generateClientID(
|
|
|
21
24
|
storageKey: string,
|
|
22
25
|
index?: number,
|
|
23
26
|
): DataID {
|
|
24
|
-
|
|
27
|
+
const internedId =
|
|
28
|
+
RelayFeatureFlags.STRING_INTERN_LEVEL <= 0
|
|
29
|
+
? id
|
|
30
|
+
: intern(id, RelayFeatureFlags.MAX_DATA_ID_LENGTH);
|
|
31
|
+
let key = internedId + ':' + storageKey;
|
|
25
32
|
if (index != null) {
|
|
26
33
|
key += ':' + index;
|
|
27
34
|
}
|
|
@@ -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.
|
|
@@ -13,24 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
-
const RelayConcreteNode = require('../util/RelayConcreteNode');
|
|
17
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
18
|
-
const RelayModernRecord = require('./RelayModernRecord');
|
|
19
|
-
const RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator');
|
|
20
|
-
const RelayRecordSourceProxy = require('../mutations/RelayRecordSourceProxy');
|
|
21
|
-
const RelayStoreReactFlightUtils = require('./RelayStoreReactFlightUtils');
|
|
22
|
-
const RelayStoreUtils = require('./RelayStoreUtils');
|
|
23
|
-
|
|
24
|
-
const cloneRelayHandleSourceField = require('./cloneRelayHandleSourceField');
|
|
25
|
-
const cloneRelayScalarHandleSourceField = require('./cloneRelayScalarHandleSourceField');
|
|
26
|
-
const getOperation = require('../util/getOperation');
|
|
27
|
-
const invariant = require('invariant');
|
|
28
|
-
|
|
29
|
-
const {isClientID} = require('./ClientID');
|
|
30
|
-
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
31
|
-
const {EXISTENT, UNKNOWN} = require('./RelayRecordState');
|
|
32
|
-
const {generateTypeID} = require('./TypeID');
|
|
33
|
-
|
|
34
16
|
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
35
17
|
import type {
|
|
36
18
|
NormalizationField,
|
|
@@ -53,6 +35,22 @@ import type {
|
|
|
53
35
|
RecordSource,
|
|
54
36
|
} from './RelayStoreTypes';
|
|
55
37
|
|
|
38
|
+
const RelayRecordSourceMutator = require('../mutations/RelayRecordSourceMutator');
|
|
39
|
+
const RelayRecordSourceProxy = require('../mutations/RelayRecordSourceProxy');
|
|
40
|
+
const getOperation = require('../util/getOperation');
|
|
41
|
+
const RelayConcreteNode = require('../util/RelayConcreteNode');
|
|
42
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
43
|
+
const {isClientID} = require('./ClientID');
|
|
44
|
+
const cloneRelayHandleSourceField = require('./cloneRelayHandleSourceField');
|
|
45
|
+
const cloneRelayScalarHandleSourceField = require('./cloneRelayScalarHandleSourceField');
|
|
46
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
47
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
48
|
+
const {EXISTENT, UNKNOWN} = require('./RelayRecordState');
|
|
49
|
+
const RelayStoreReactFlightUtils = require('./RelayStoreReactFlightUtils');
|
|
50
|
+
const RelayStoreUtils = require('./RelayStoreUtils');
|
|
51
|
+
const {generateTypeID} = require('./TypeID');
|
|
52
|
+
const invariant = require('invariant');
|
|
53
|
+
|
|
56
54
|
export type Availability = {|
|
|
57
55
|
+status: 'available' | 'missing',
|
|
58
56
|
+mostRecentlyInvalidatedAt: ?number,
|
|
@@ -75,12 +73,8 @@ const {
|
|
|
75
73
|
STREAM,
|
|
76
74
|
TYPE_DISCRIMINATOR,
|
|
77
75
|
} = RelayConcreteNode;
|
|
78
|
-
const {
|
|
79
|
-
|
|
80
|
-
getModuleOperationKey,
|
|
81
|
-
getStorageKey,
|
|
82
|
-
getArgumentValues,
|
|
83
|
-
} = RelayStoreUtils;
|
|
76
|
+
const {ROOT_ID, getModuleOperationKey, getStorageKey, getArgumentValues} =
|
|
77
|
+
RelayStoreUtils;
|
|
84
78
|
|
|
85
79
|
/**
|
|
86
80
|
* Synchronously check whether the records required to fulfill the given
|
|
@@ -211,7 +205,6 @@ class DataChecker {
|
|
|
211
205
|
'RelayAsyncLoader(): Undefined variable `%s`.',
|
|
212
206
|
name,
|
|
213
207
|
);
|
|
214
|
-
// $FlowFixMe[cannot-write]
|
|
215
208
|
return this._variables[name];
|
|
216
209
|
}
|
|
217
210
|
|
|
@@ -595,10 +588,8 @@ class DataChecker {
|
|
|
595
588
|
const prevMutator = this._mutator;
|
|
596
589
|
const prevRecordSourceProxy = this._recordSourceProxy;
|
|
597
590
|
|
|
598
|
-
const [
|
|
599
|
-
|
|
600
|
-
recordSourceProxy,
|
|
601
|
-
] = this._getMutatorAndRecordProxyForActor(actorIdentifier);
|
|
591
|
+
const [mutator, recordSourceProxy] =
|
|
592
|
+
this._getMutatorAndRecordProxyForActor(actorIdentifier);
|
|
602
593
|
|
|
603
594
|
this._source = this._getSourceForActor(actorIdentifier);
|
|
604
595
|
this._mutator = mutator;
|
|
@@ -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.
|
|
@@ -13,44 +13,22 @@
|
|
|
13
13
|
|
|
14
14
|
'use strict';
|
|
15
15
|
|
|
16
|
-
const RelayError = require('../util/RelayError');
|
|
17
|
-
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
18
|
-
const RelayModernRecord = require('./RelayModernRecord');
|
|
19
|
-
const RelayObservable = require('../network/RelayObservable');
|
|
20
|
-
const RelayRecordSource = require('./RelayRecordSource');
|
|
21
|
-
const RelayResponseNormalizer = require('./RelayResponseNormalizer');
|
|
22
|
-
|
|
23
|
-
const generateID = require('../util/generateID');
|
|
24
|
-
const getOperation = require('../util/getOperation');
|
|
25
|
-
const invariant = require('invariant');
|
|
26
|
-
const stableCopy = require('../util/stableCopy');
|
|
27
|
-
const warning = require('warning');
|
|
28
|
-
const withDuration = require('../util/withDuration');
|
|
29
|
-
|
|
30
|
-
const {generateClientID, generateUniqueClientID} = require('./ClientID');
|
|
31
|
-
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
32
|
-
const {
|
|
33
|
-
createNormalizationSelector,
|
|
34
|
-
createReaderSelector,
|
|
35
|
-
} = require('./RelayModernSelector');
|
|
36
|
-
const {ROOT_TYPE, TYPENAME_KEY, getStorageKey} = require('./RelayStoreUtils');
|
|
37
|
-
|
|
38
16
|
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
39
17
|
import type {
|
|
40
18
|
GraphQLResponse,
|
|
41
|
-
GraphQLSingularResponse,
|
|
42
19
|
GraphQLResponseWithData,
|
|
20
|
+
GraphQLSingularResponse,
|
|
43
21
|
ReactFlightServerTree,
|
|
44
22
|
} from '../network/RelayNetworkTypes';
|
|
45
23
|
import type {Sink, Subscription} from '../network/RelayObservable';
|
|
46
24
|
import type {
|
|
47
25
|
DeferPlaceholder,
|
|
48
26
|
FollowupPayload,
|
|
49
|
-
RequestDescriptor,
|
|
50
27
|
HandleFieldPayload,
|
|
51
28
|
IncrementalDataPlaceholder,
|
|
52
29
|
LogFunction,
|
|
53
30
|
ModuleImportPayload,
|
|
31
|
+
MutationParameters,
|
|
54
32
|
NormalizationSelector,
|
|
55
33
|
OperationDescriptor,
|
|
56
34
|
OperationLoader,
|
|
@@ -58,11 +36,12 @@ import type {
|
|
|
58
36
|
OptimisticResponseConfig,
|
|
59
37
|
OptimisticUpdate,
|
|
60
38
|
PublishQueue,
|
|
39
|
+
ReactFlightClientResponse,
|
|
61
40
|
ReactFlightPayloadDeserializer,
|
|
62
41
|
ReactFlightServerErrorHandler,
|
|
63
|
-
ReactFlightClientResponse,
|
|
64
42
|
Record,
|
|
65
43
|
RelayResponsePayload,
|
|
44
|
+
RequestDescriptor,
|
|
66
45
|
SelectorStoreUpdater,
|
|
67
46
|
Store,
|
|
68
47
|
StreamPlaceholder,
|
|
@@ -74,11 +53,31 @@ import type {
|
|
|
74
53
|
NormalizationSelectableNode,
|
|
75
54
|
NormalizationSplitOperation,
|
|
76
55
|
} from '../util/NormalizationNode';
|
|
77
|
-
import type {DataID,
|
|
56
|
+
import type {DataID, Disposable, Variables} from '../util/RelayRuntimeTypes';
|
|
78
57
|
import type {GetDataID} from './RelayResponseNormalizer';
|
|
79
58
|
import type {NormalizationOptions} from './RelayResponseNormalizer';
|
|
80
59
|
|
|
81
|
-
|
|
60
|
+
const RelayObservable = require('../network/RelayObservable');
|
|
61
|
+
const generateID = require('../util/generateID');
|
|
62
|
+
const getOperation = require('../util/getOperation');
|
|
63
|
+
const RelayError = require('../util/RelayError');
|
|
64
|
+
const RelayFeatureFlags = require('../util/RelayFeatureFlags');
|
|
65
|
+
const stableCopy = require('../util/stableCopy');
|
|
66
|
+
const withDuration = require('../util/withDuration');
|
|
67
|
+
const {generateClientID, generateUniqueClientID} = require('./ClientID');
|
|
68
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
69
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
70
|
+
const {
|
|
71
|
+
createNormalizationSelector,
|
|
72
|
+
createReaderSelector,
|
|
73
|
+
} = require('./RelayModernSelector');
|
|
74
|
+
const RelayRecordSource = require('./RelayRecordSource');
|
|
75
|
+
const RelayResponseNormalizer = require('./RelayResponseNormalizer');
|
|
76
|
+
const {ROOT_TYPE, TYPENAME_KEY, getStorageKey} = require('./RelayStoreUtils');
|
|
77
|
+
const invariant = require('invariant');
|
|
78
|
+
const warning = require('warning');
|
|
79
|
+
|
|
80
|
+
export type ExecuteConfig<TMutation: MutationParameters> = {|
|
|
82
81
|
+actorIdentifier: ActorIdentifier,
|
|
83
82
|
+getDataID: GetDataID,
|
|
84
83
|
+getPublishQueue: (actorIdentifier: ActorIdentifier) => PublishQueue,
|
|
@@ -88,7 +87,7 @@ export type ExecuteConfig = {|
|
|
|
88
87
|
+operationExecutions: Map<string, ActiveState>,
|
|
89
88
|
+operationLoader: ?OperationLoader,
|
|
90
89
|
+operationTracker: OperationTracker,
|
|
91
|
-
+optimisticConfig: ?OptimisticResponseConfig
|
|
90
|
+
+optimisticConfig: ?OptimisticResponseConfig<TMutation>,
|
|
92
91
|
+reactFlightPayloadDeserializer?: ?ReactFlightPayloadDeserializer,
|
|
93
92
|
+reactFlightServerErrorHandler?: ?ReactFlightServerErrorHandler,
|
|
94
93
|
+scheduler?: ?TaskScheduler,
|
|
@@ -96,7 +95,7 @@ export type ExecuteConfig = {|
|
|
|
96
95
|
+sink: Sink<GraphQLResponse>,
|
|
97
96
|
+source: RelayObservable<GraphQLResponse>,
|
|
98
97
|
+treatMissingFieldsAsNull: boolean,
|
|
99
|
-
+updater?: ?SelectorStoreUpdater
|
|
98
|
+
+updater?: ?SelectorStoreUpdater<TMutation['response']>,
|
|
100
99
|
+log: LogFunction,
|
|
101
100
|
|};
|
|
102
101
|
|
|
@@ -125,7 +124,9 @@ type IncrementalGraphQLResponse = {|
|
|
|
125
124
|
response: GraphQLResponseWithData,
|
|
126
125
|
|};
|
|
127
126
|
|
|
128
|
-
function execute
|
|
127
|
+
function execute<TMutation: MutationParameters>(
|
|
128
|
+
config: ExecuteConfig<TMutation>,
|
|
129
|
+
): Executor<TMutation> {
|
|
129
130
|
return new Executor(config);
|
|
130
131
|
}
|
|
131
132
|
|
|
@@ -134,7 +135,7 @@ function execute(config: ExecuteConfig): Executor {
|
|
|
134
135
|
* including optimistic payloads, standard payloads, resolution of match
|
|
135
136
|
* dependencies, etc.
|
|
136
137
|
*/
|
|
137
|
-
class Executor {
|
|
138
|
+
class Executor<TMutation: MutationParameters> {
|
|
138
139
|
_actorIdentifier: ActorIdentifier;
|
|
139
140
|
_getDataID: GetDataID;
|
|
140
141
|
_treatMissingFieldsAsNull: boolean;
|
|
@@ -148,7 +149,7 @@ class Executor {
|
|
|
148
149
|
_operationLoader: ?OperationLoader;
|
|
149
150
|
_operationTracker: OperationTracker;
|
|
150
151
|
_operationUpdateEpochs: Map<string, number>;
|
|
151
|
-
_optimisticUpdates: null | Array<OptimisticUpdate
|
|
152
|
+
_optimisticUpdates: null | Array<OptimisticUpdate<TMutation>>;
|
|
152
153
|
_pendingModulePayloadsCount: number;
|
|
153
154
|
+_getPublishQueue: (actorIdentifier: ActorIdentifier) => PublishQueue;
|
|
154
155
|
_reactFlightPayloadDeserializer: ?ReactFlightPayloadDeserializer;
|
|
@@ -163,7 +164,7 @@ class Executor {
|
|
|
163
164
|
_state: 'started' | 'loading_incremental' | 'loading_final' | 'completed';
|
|
164
165
|
+_getStore: (actorIdentifier: ActorIdentifier) => Store;
|
|
165
166
|
_subscriptions: Map<number, Subscription>;
|
|
166
|
-
_updater: ?SelectorStoreUpdater
|
|
167
|
+
_updater: ?SelectorStoreUpdater<TMutation['response']>;
|
|
167
168
|
_asyncStoreUpdateDisposable: ?Disposable;
|
|
168
169
|
_completeFns: Array<() => void>;
|
|
169
170
|
+_retainDisposables: Map<ActorIdentifier, Disposable>;
|
|
@@ -191,7 +192,7 @@ class Executor {
|
|
|
191
192
|
treatMissingFieldsAsNull,
|
|
192
193
|
updater,
|
|
193
194
|
log,
|
|
194
|
-
}: ExecuteConfig): void {
|
|
195
|
+
}: ExecuteConfig<TMutation>): void {
|
|
195
196
|
this._actorIdentifier = actorIdentifier;
|
|
196
197
|
this._getDataID = getDataID;
|
|
197
198
|
this._treatMissingFieldsAsNull = treatMissingFieldsAsNull;
|
|
@@ -447,7 +448,8 @@ class Executor {
|
|
|
447
448
|
error.stack;
|
|
448
449
|
throw error;
|
|
449
450
|
} else {
|
|
450
|
-
const responseWithData: GraphQLResponseWithData =
|
|
451
|
+
const responseWithData: GraphQLResponseWithData =
|
|
452
|
+
(response: $FlowFixMe);
|
|
451
453
|
results.push(responseWithData);
|
|
452
454
|
}
|
|
453
455
|
});
|
|
@@ -522,10 +524,8 @@ class Executor {
|
|
|
522
524
|
return;
|
|
523
525
|
}
|
|
524
526
|
|
|
525
|
-
const [
|
|
526
|
-
|
|
527
|
-
incrementalResponses,
|
|
528
|
-
] = partitionGraphQLResponses(responsesWithData);
|
|
527
|
+
const [nonIncrementalResponses, incrementalResponses] =
|
|
528
|
+
partitionGraphQLResponses(responsesWithData);
|
|
529
529
|
const hasNonIncrementalResponses = nonIncrementalResponses.length > 0;
|
|
530
530
|
|
|
531
531
|
// In theory this doesn't preserve the ordering of the batch.
|
|
@@ -562,9 +562,8 @@ class Executor {
|
|
|
562
562
|
}
|
|
563
563
|
|
|
564
564
|
if (incrementalResponses.length > 0) {
|
|
565
|
-
const payloadFollowups =
|
|
566
|
-
incrementalResponses
|
|
567
|
-
);
|
|
565
|
+
const payloadFollowups =
|
|
566
|
+
this._processIncrementalResponses(incrementalResponses);
|
|
568
567
|
|
|
569
568
|
this._processPayloadFollowups(payloadFollowups);
|
|
570
569
|
}
|
|
@@ -577,7 +576,8 @@ class Executor {
|
|
|
577
576
|
__relay_subscription_root_id: this._operation.fragment.dataID,
|
|
578
577
|
};
|
|
579
578
|
} else {
|
|
580
|
-
responsesWithData[0].extensions.__relay_subscription_root_id =
|
|
579
|
+
responsesWithData[0].extensions.__relay_subscription_root_id =
|
|
580
|
+
this._operation.fragment.dataID;
|
|
581
581
|
}
|
|
582
582
|
}
|
|
583
583
|
|
|
@@ -600,7 +600,7 @@ class Executor {
|
|
|
600
600
|
|
|
601
601
|
_processOptimisticResponse(
|
|
602
602
|
response: ?GraphQLResponseWithData,
|
|
603
|
-
updater: ?SelectorStoreUpdater
|
|
603
|
+
updater: ?SelectorStoreUpdater<TMutation['response']>,
|
|
604
604
|
treatMissingFieldsAsNull: boolean,
|
|
605
605
|
): void {
|
|
606
606
|
invariant(
|
|
@@ -611,7 +611,7 @@ class Executor {
|
|
|
611
611
|
if (response == null && updater == null) {
|
|
612
612
|
return;
|
|
613
613
|
}
|
|
614
|
-
const optimisticUpdates: Array<OptimisticUpdate
|
|
614
|
+
const optimisticUpdates: Array<OptimisticUpdate<TMutation>> = [];
|
|
615
615
|
if (response) {
|
|
616
616
|
const payload = normalizeResponse(
|
|
617
617
|
response,
|
|
@@ -662,7 +662,7 @@ class Executor {
|
|
|
662
662
|
|
|
663
663
|
_processOptimisticFollowups(
|
|
664
664
|
payload: RelayResponsePayload,
|
|
665
|
-
optimisticUpdates: Array<OptimisticUpdate
|
|
665
|
+
optimisticUpdates: Array<OptimisticUpdate<TMutation>>,
|
|
666
666
|
): void {
|
|
667
667
|
if (payload.followupPayloads && payload.followupPayloads.length) {
|
|
668
668
|
const followupPayloads = payload.followupPayloads;
|
|
@@ -676,10 +676,8 @@ class Executor {
|
|
|
676
676
|
if (operation == null) {
|
|
677
677
|
this._processAsyncOptimisticModuleImport(followupPayload);
|
|
678
678
|
} else {
|
|
679
|
-
const moduleImportOptimisticUpdates =
|
|
680
|
-
operation,
|
|
681
|
-
followupPayload,
|
|
682
|
-
);
|
|
679
|
+
const moduleImportOptimisticUpdates =
|
|
680
|
+
this._processOptimisticModuleImport(operation, followupPayload);
|
|
683
681
|
optimisticUpdates.push(...moduleImportOptimisticUpdates);
|
|
684
682
|
}
|
|
685
683
|
break;
|
|
@@ -748,7 +746,7 @@ class Executor {
|
|
|
748
746
|
_processOptimisticModuleImport(
|
|
749
747
|
normalizationRootNode: NormalizationRootNode,
|
|
750
748
|
moduleImportPayload: ModuleImportPayload,
|
|
751
|
-
): $ReadOnlyArray<OptimisticUpdate
|
|
749
|
+
): $ReadOnlyArray<OptimisticUpdate<TMutation>> {
|
|
752
750
|
const operation = getOperation(normalizationRootNode);
|
|
753
751
|
const optimisticUpdates = [];
|
|
754
752
|
const modulePayload = this._normalizeFollowupPayload(
|
|
@@ -774,10 +772,8 @@ class Executor {
|
|
|
774
772
|
if (operation == null || this._state !== 'started') {
|
|
775
773
|
return;
|
|
776
774
|
}
|
|
777
|
-
const moduleImportOptimisticUpdates =
|
|
778
|
-
operation,
|
|
779
|
-
moduleImportPayload,
|
|
780
|
-
);
|
|
775
|
+
const moduleImportOptimisticUpdates =
|
|
776
|
+
this._processOptimisticModuleImport(operation, moduleImportPayload);
|
|
781
777
|
moduleImportOptimisticUpdates.forEach(update =>
|
|
782
778
|
this._getPublishQueueAndSaveActor().applyUpdate(update),
|
|
783
779
|
);
|
|
@@ -1179,9 +1175,8 @@ class Executor {
|
|
|
1179
1175
|
// If there were any queued responses, process them now that placeholders
|
|
1180
1176
|
// are in place
|
|
1181
1177
|
if (pendingResponses != null) {
|
|
1182
|
-
const payloadFollowups =
|
|
1183
|
-
pendingResponses
|
|
1184
|
-
);
|
|
1178
|
+
const payloadFollowups =
|
|
1179
|
+
this._processIncrementalResponses(pendingResponses);
|
|
1185
1180
|
this._processPayloadFollowups(payloadFollowups);
|
|
1186
1181
|
}
|
|
1187
1182
|
}
|
|
@@ -1231,10 +1226,7 @@ class Executor {
|
|
|
1231
1226
|
// but Relay records paths relative to the parent of the stream node:
|
|
1232
1227
|
// therefore we strip the last two elements just to lookup the path
|
|
1233
1228
|
// (the item index is used later to insert the element in the list)
|
|
1234
|
-
const pathKey = path
|
|
1235
|
-
.slice(0, -2)
|
|
1236
|
-
.map(String)
|
|
1237
|
-
.join('.');
|
|
1229
|
+
const pathKey = path.slice(0, -2).map(String).join('.');
|
|
1238
1230
|
let resultForPath = resultForLabel.get(pathKey);
|
|
1239
1231
|
if (resultForPath == null) {
|
|
1240
1232
|
resultForPath = {kind: 'response', responses: [incrementalResponse]};
|
|
@@ -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,18 +12,17 @@
|
|
|
12
12
|
|
|
13
13
|
'use strict';
|
|
14
14
|
|
|
15
|
-
const invariant = require('invariant');
|
|
16
|
-
|
|
17
|
-
const {getArgumentValues} = require('./RelayStoreUtils');
|
|
18
|
-
|
|
19
15
|
import type {
|
|
20
|
-
NormalizationLocalArgumentDefinition,
|
|
21
16
|
NormalizationArgument,
|
|
17
|
+
NormalizationLocalArgumentDefinition,
|
|
22
18
|
NormalizationOperation,
|
|
23
19
|
} from '../util/NormalizationNode';
|
|
24
20
|
import type {ReaderFragment} from '../util/ReaderNode';
|
|
25
21
|
import type {Variables} from '../util/RelayRuntimeTypes';
|
|
26
22
|
|
|
23
|
+
const {getArgumentValues} = require('./RelayStoreUtils');
|
|
24
|
+
const invariant = require('invariant');
|
|
25
|
+
|
|
27
26
|
/**
|
|
28
27
|
* Determines the variables that are in scope for a fragment given the variables
|
|
29
28
|
* in scope at the root query as well as any arguments applied at the fragment
|
|
@@ -41,7 +40,6 @@ function getFragmentVariables(
|
|
|
41
40
|
if (argumentVariables.hasOwnProperty(definition.name)) {
|
|
42
41
|
return;
|
|
43
42
|
}
|
|
44
|
-
// $FlowFixMe[cannot-spread-interface]
|
|
45
43
|
variables = variables || {...argumentVariables};
|
|
46
44
|
switch (definition.kind) {
|
|
47
45
|
case 'LocalArgument':
|
|
@@ -58,12 +56,9 @@ function getFragmentVariables(
|
|
|
58
56
|
* RelayStoreUtils.getStableVariableValue() that variable keys are all
|
|
59
57
|
* present.
|
|
60
58
|
*/
|
|
61
|
-
// $FlowFixMe[incompatible-use]
|
|
62
59
|
variables[definition.name] = undefined;
|
|
63
60
|
break;
|
|
64
61
|
}
|
|
65
|
-
// $FlowFixMe[incompatible-use]
|
|
66
|
-
// $FlowFixMe[cannot-write]
|
|
67
62
|
variables[definition.name] = rootVariables[definition.name];
|
|
68
63
|
break;
|
|
69
64
|
default:
|
|
@@ -92,7 +87,6 @@ function getOperationVariables(
|
|
|
92
87
|
const operationVariables = {};
|
|
93
88
|
operation.argumentDefinitions.forEach(def => {
|
|
94
89
|
let value = def.defaultValue;
|
|
95
|
-
// $FlowFixMe[cannot-write]
|
|
96
90
|
if (variables[def.name] != null) {
|
|
97
91
|
value = variables[def.name];
|
|
98
92
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
* @emails oncall+relay
|
|
8
|
+
* @flow
|
|
9
|
+
* @format
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import type {
|
|
13
|
+
DataChunk,
|
|
14
|
+
GraphModeResponse,
|
|
15
|
+
RecordChunk,
|
|
16
|
+
} from './RelayExperimentalGraphResponseTransform';
|
|
17
|
+
import type {MutableRecordSource, Record} from './RelayStoreTypes';
|
|
18
|
+
|
|
19
|
+
const RelayModernRecord = require('./RelayModernRecord');
|
|
20
|
+
const invariant = require('invariant');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Given a stream of GraphMode chunks, populate a MutableRecordSource.
|
|
24
|
+
*/
|
|
25
|
+
export function handleGraphModeResponse(
|
|
26
|
+
recordSource: MutableRecordSource,
|
|
27
|
+
response: GraphModeResponse,
|
|
28
|
+
): MutableRecordSource {
|
|
29
|
+
const handler = new GraphModeHandler(recordSource);
|
|
30
|
+
return handler.populateRecordSource(response);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
class GraphModeHandler {
|
|
34
|
+
_recordSource: MutableRecordSource;
|
|
35
|
+
_streamIdToCacheKey: Map<number, string>;
|
|
36
|
+
constructor(recordSource: MutableRecordSource) {
|
|
37
|
+
this._recordSource = recordSource;
|
|
38
|
+
this._streamIdToCacheKey = new Map();
|
|
39
|
+
}
|
|
40
|
+
populateRecordSource(response: GraphModeResponse): MutableRecordSource {
|
|
41
|
+
for (const chunk of response) {
|
|
42
|
+
switch (chunk.$kind) {
|
|
43
|
+
case 'Record':
|
|
44
|
+
this._handleRecordChunk(chunk);
|
|
45
|
+
break;
|
|
46
|
+
case 'Extend': {
|
|
47
|
+
const cacheKey = this._lookupCacheKey(chunk.$streamID);
|
|
48
|
+
const record = this._recordSource.get(cacheKey);
|
|
49
|
+
invariant(
|
|
50
|
+
record != null,
|
|
51
|
+
`Expected to have a record for cache key ${cacheKey}`,
|
|
52
|
+
);
|
|
53
|
+
this._populateRecord(record, chunk);
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case 'Complete':
|
|
57
|
+
this._streamIdToCacheKey.clear();
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
(chunk.$kind: empty);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return this._recordSource;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
_handleRecordChunk(chunk: RecordChunk) {
|
|
67
|
+
const cacheKey = chunk.__id;
|
|
68
|
+
let record = this._recordSource.get(cacheKey);
|
|
69
|
+
if (record == null) {
|
|
70
|
+
record = RelayModernRecord.create(cacheKey, chunk.__typename);
|
|
71
|
+
this._recordSource.set(cacheKey, record);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this._streamIdToCacheKey.set(chunk.$streamID, cacheKey);
|
|
75
|
+
this._populateRecord(record, chunk);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
_populateRecord(parentRecord: Record, chunk: DataChunk) {
|
|
79
|
+
for (const [key, value] of Object.entries(chunk)) {
|
|
80
|
+
switch (key) {
|
|
81
|
+
case '$streamID':
|
|
82
|
+
case '$kind':
|
|
83
|
+
case '__typename':
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
if (
|
|
87
|
+
typeof value !== 'object' ||
|
|
88
|
+
value == null ||
|
|
89
|
+
Array.isArray(value)
|
|
90
|
+
) {
|
|
91
|
+
RelayModernRecord.setValue(parentRecord, key, value);
|
|
92
|
+
} else {
|
|
93
|
+
if (value.hasOwnProperty('__id')) {
|
|
94
|
+
// Singular
|
|
95
|
+
const streamID = ((value.__id: any): number);
|
|
96
|
+
const id = this._lookupCacheKey(streamID);
|
|
97
|
+
RelayModernRecord.setLinkedRecordID(parentRecord, key, id);
|
|
98
|
+
} else if (value.hasOwnProperty('__ids')) {
|
|
99
|
+
// Plural
|
|
100
|
+
const streamIDs = ((value.__ids: any): Array<number | null>);
|
|
101
|
+
const ids = streamIDs.map(sID => {
|
|
102
|
+
return sID == null ? null : this._lookupCacheKey(sID);
|
|
103
|
+
});
|
|
104
|
+
RelayModernRecord.setLinkedRecordIDs(parentRecord, key, ids);
|
|
105
|
+
} else {
|
|
106
|
+
invariant(false, 'Expected object to have either __id or __ids.');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
_lookupCacheKey(streamID: number): string {
|
|
114
|
+
const cacheKey = this._streamIdToCacheKey.get(streamID);
|
|
115
|
+
invariant(
|
|
116
|
+
cacheKey != null,
|
|
117
|
+
`Expected to have a cacheKey for $streamID ${streamID}`,
|
|
118
|
+
);
|
|
119
|
+
return cacheKey;
|
|
120
|
+
}
|
|
121
|
+
}
|