relay-runtime 12.0.0 → 13.0.0-rc.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.
Files changed (138) hide show
  1. package/handlers/RelayDefaultHandlerProvider.js.flow +2 -2
  2. package/handlers/connection/ConnectionHandler.js.flow +8 -17
  3. package/handlers/connection/MutationHandlers.js.flow +7 -11
  4. package/index.js +1 -1
  5. package/index.js.flow +40 -33
  6. package/lib/handlers/connection/ConnectionHandler.js +12 -18
  7. package/lib/handlers/connection/MutationHandlers.js +3 -6
  8. package/lib/index.js +45 -45
  9. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +8 -4
  10. package/lib/multi-actor-environment/MultiActorEnvironment.js +35 -22
  11. package/lib/multi-actor-environment/index.js +2 -2
  12. package/lib/mutations/RelayDeclarativeMutationConfig.js +4 -1
  13. package/lib/mutations/RelayRecordProxy.js +3 -2
  14. package/lib/mutations/RelayRecordSourceMutator.js +3 -2
  15. package/lib/mutations/RelayRecordSourceProxy.js +12 -4
  16. package/lib/mutations/RelayRecordSourceSelectorProxy.js +12 -4
  17. package/lib/mutations/applyOptimisticMutation.js +6 -6
  18. package/lib/mutations/commitMutation.js +15 -14
  19. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +238 -0
  20. package/lib/mutations/validateMutation.js +6 -6
  21. package/lib/network/ConvertToExecuteFunction.js +2 -1
  22. package/lib/network/RelayNetwork.js +3 -2
  23. package/lib/network/RelayObservable.js +1 -3
  24. package/lib/network/RelayQueryResponseCache.js +2 -2
  25. package/lib/network/wrapNetworkWithLogObserver.js +2 -1
  26. package/lib/query/GraphQLTag.js +2 -1
  27. package/lib/query/fetchQuery.js +6 -5
  28. package/lib/query/fetchQuery_DEPRECATED.js +2 -1
  29. package/lib/store/ClientID.js +7 -1
  30. package/lib/store/DataChecker.js +16 -17
  31. package/lib/store/OperationExecutor.js +13 -13
  32. package/lib/store/RelayConcreteVariables.js +6 -9
  33. package/lib/store/RelayModernEnvironment.js +66 -42
  34. package/lib/store/RelayModernFragmentSpecResolver.js +8 -8
  35. package/lib/store/RelayModernOperationDescriptor.js +2 -1
  36. package/lib/store/RelayModernRecord.js +12 -11
  37. package/lib/store/RelayModernSelector.js +14 -8
  38. package/lib/store/RelayModernStore.js +14 -15
  39. package/lib/store/RelayPublishQueue.js +11 -5
  40. package/lib/store/RelayReader.js +130 -37
  41. package/lib/store/RelayReferenceMarker.js +10 -11
  42. package/lib/store/RelayResponseNormalizer.js +25 -22
  43. package/lib/store/RelayStoreReactFlightUtils.js +3 -3
  44. package/lib/store/RelayStoreSubscriptions.js +6 -4
  45. package/lib/store/RelayStoreUtils.js +5 -5
  46. package/lib/store/ResolverCache.js +6 -6
  47. package/lib/store/ResolverFragments.js +9 -5
  48. package/lib/store/cloneRelayHandleSourceField.js +5 -4
  49. package/lib/store/cloneRelayScalarHandleSourceField.js +5 -4
  50. package/lib/store/createRelayContext.js +3 -1
  51. package/lib/store/readInlineData.js +6 -2
  52. package/lib/subscription/requestSubscription.js +5 -5
  53. package/lib/util/RelayConcreteNode.js +1 -0
  54. package/lib/util/RelayFeatureFlags.js +7 -1
  55. package/lib/util/RelayRuntimeTypes.js +0 -6
  56. package/lib/util/StringInterner.js +71 -0
  57. package/lib/util/getFragmentIdentifier.js +15 -7
  58. package/lib/util/getOperation.js +2 -1
  59. package/lib/util/getPaginationVariables.js +2 -3
  60. package/lib/util/getRelayHandleKey.js +2 -2
  61. package/lib/util/getRequestIdentifier.js +2 -2
  62. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +27 -19
  63. package/multi-actor-environment/ActorUtils.js.flow +2 -2
  64. package/multi-actor-environment/MultiActorEnvironment.js.flow +45 -24
  65. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +27 -11
  66. package/multi-actor-environment/index.js.flow +1 -2
  67. package/mutations/RelayDeclarativeMutationConfig.js.flow +32 -26
  68. package/mutations/RelayRecordProxy.js.flow +4 -5
  69. package/mutations/RelayRecordSourceMutator.js.flow +4 -6
  70. package/mutations/RelayRecordSourceProxy.js.flow +19 -10
  71. package/mutations/RelayRecordSourceSelectorProxy.js.flow +15 -5
  72. package/mutations/applyOptimisticMutation.js.flow +13 -14
  73. package/mutations/commitLocalUpdate.js.flow +1 -1
  74. package/mutations/commitMutation.js.flow +35 -48
  75. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +309 -0
  76. package/mutations/validateMutation.js.flow +19 -17
  77. package/network/ConvertToExecuteFunction.js.flow +2 -2
  78. package/network/RelayNetwork.js.flow +4 -5
  79. package/network/RelayObservable.js.flow +1 -3
  80. package/network/RelayQueryResponseCache.js.flow +3 -3
  81. package/network/wrapNetworkWithLogObserver.js.flow +8 -7
  82. package/package.json +1 -1
  83. package/query/GraphQLTag.js.flow +9 -9
  84. package/query/PreloadableQueryRegistry.js.flow +2 -1
  85. package/query/fetchQuery.js.flow +11 -13
  86. package/query/fetchQueryInternal.js.flow +6 -9
  87. package/query/fetchQuery_DEPRECATED.js.flow +6 -6
  88. package/relay-runtime.js +2 -2
  89. package/relay-runtime.min.js +2 -2
  90. package/store/ClientID.js.flow +9 -2
  91. package/store/DataChecker.js.flow +20 -29
  92. package/store/OperationExecutor.js.flow +54 -62
  93. package/store/RelayConcreteVariables.js.flow +4 -10
  94. package/store/RelayModernEnvironment.js.flow +56 -27
  95. package/store/RelayModernFragmentSpecResolver.js.flow +17 -19
  96. package/store/RelayModernOperationDescriptor.js.flow +10 -11
  97. package/store/RelayModernRecord.js.flow +19 -12
  98. package/store/RelayModernSelector.js.flow +24 -14
  99. package/store/RelayModernStore.js.flow +21 -24
  100. package/store/RelayOperationTracker.js.flow +11 -17
  101. package/store/RelayOptimisticRecordSource.js.flow +2 -2
  102. package/store/RelayPublishQueue.js.flow +42 -23
  103. package/store/RelayReader.js.flow +180 -60
  104. package/store/RelayRecordSource.js.flow +2 -2
  105. package/store/RelayReferenceMarker.js.flow +12 -15
  106. package/store/RelayResponseNormalizer.js.flow +43 -41
  107. package/store/RelayStoreReactFlightUtils.js.flow +3 -4
  108. package/store/RelayStoreSubscriptions.js.flow +9 -8
  109. package/store/RelayStoreTypes.js.flow +72 -29
  110. package/store/RelayStoreUtils.js.flow +8 -9
  111. package/store/ResolverCache.js.flow +16 -14
  112. package/store/ResolverFragments.js.flow +15 -22
  113. package/store/StoreInspector.js.flow +2 -2
  114. package/store/TypeID.js.flow +1 -1
  115. package/store/ViewerPattern.js.flow +2 -2
  116. package/store/cloneRelayHandleSourceField.js.flow +5 -6
  117. package/store/cloneRelayScalarHandleSourceField.js.flow +5 -6
  118. package/store/createFragmentSpecResolver.js.flow +3 -4
  119. package/store/createRelayContext.js.flow +2 -2
  120. package/store/normalizeRelayPayload.js.flow +6 -7
  121. package/store/readInlineData.js.flow +7 -8
  122. package/subscription/requestSubscription.js.flow +16 -24
  123. package/util/ReaderNode.js.flow +9 -0
  124. package/util/RelayConcreteNode.js.flow +1 -0
  125. package/util/RelayFeatureFlags.js.flow +14 -2
  126. package/util/RelayReplaySubject.js.flow +2 -3
  127. package/util/RelayRuntimeTypes.js.flow +69 -2
  128. package/util/StringInterner.js.flow +69 -0
  129. package/util/createPayloadFor3DField.js.flow +3 -3
  130. package/util/getFragmentIdentifier.js.flow +27 -15
  131. package/util/getOperation.js.flow +2 -2
  132. package/util/getPaginationMetadata.js.flow +5 -7
  133. package/util/getPaginationVariables.js.flow +5 -9
  134. package/util/getPendingOperationsForFragment.js.flow +2 -2
  135. package/util/getRefetchMetadata.js.flow +6 -7
  136. package/util/getRelayHandleKey.js.flow +1 -2
  137. package/util/getRequestIdentifier.js.flow +3 -3
  138. package/util/resolveImmediate.js.flow +1 -1
@@ -4,7 +4,7 @@
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
- let key = id + ':' + storageKey;
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
  }
@@ -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
- ROOT_ID,
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
- mutator,
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;
@@ -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, Variables, Disposable} from '../util/RelayRuntimeTypes';
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
- export type ExecuteConfig = {|
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(config: ExecuteConfig): Executor {
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 = (response: $FlowFixMe);
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
- nonIncrementalResponses,
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 = this._processIncrementalResponses(
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 = this._operation.fragment.dataID;
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 = this._processOptimisticModuleImport(
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 = this._processOptimisticModuleImport(
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 = this._processIncrementalResponses(
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]};
@@ -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
  }
@@ -13,25 +13,6 @@
13
13
 
14
14
  'use strict';
15
15
 
16
- const OperationExecutor = require('./OperationExecutor');
17
- const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
18
- const RelayFeatureFlags = require('../util/RelayFeatureFlags');
19
- const RelayObservable = require('../network/RelayObservable');
20
- const RelayOperationTracker = require('../store/RelayOperationTracker');
21
- const RelayPublishQueue = require('./RelayPublishQueue');
22
- const RelayRecordSource = require('./RelayRecordSource');
23
-
24
- const defaultGetDataID = require('./defaultGetDataID');
25
- const defaultRequiredFieldLogger = require('./defaultRequiredFieldLogger');
26
- const invariant = require('invariant');
27
- const registerEnvironmentWithDevTools = require('../util/registerEnvironmentWithDevTools');
28
- const wrapNetworkWithLogObserver = require('../network/wrapNetworkWithLogObserver');
29
-
30
- const {
31
- INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
32
- assertInternalActorIndentifier,
33
- } = require('../multi-actor-environment/ActorIdentifier');
34
-
35
16
  import type {HandlerProvider} from '../handlers/RelayDefaultHandlerProvider';
36
17
  import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
37
18
  import type {
@@ -47,6 +28,7 @@ import type {
47
28
  IEnvironment,
48
29
  LogFunction,
49
30
  MissingFieldHandler,
31
+ MutationParameters,
50
32
  OperationAvailability,
51
33
  OperationDescriptor,
52
34
  OperationLoader,
@@ -64,6 +46,23 @@ import type {
64
46
  StoreUpdater,
65
47
  } from './RelayStoreTypes';
66
48
 
49
+ const RelayDefaultHandlerProvider = require('../handlers/RelayDefaultHandlerProvider');
50
+ const {
51
+ INTERNAL_ACTOR_IDENTIFIER_DO_NOT_USE,
52
+ assertInternalActorIndentifier,
53
+ } = require('../multi-actor-environment/ActorIdentifier');
54
+ const RelayObservable = require('../network/RelayObservable');
55
+ const wrapNetworkWithLogObserver = require('../network/wrapNetworkWithLogObserver');
56
+ const RelayOperationTracker = require('../store/RelayOperationTracker');
57
+ const registerEnvironmentWithDevTools = require('../util/registerEnvironmentWithDevTools');
58
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
59
+ const defaultGetDataID = require('./defaultGetDataID');
60
+ const defaultRequiredFieldLogger = require('./defaultRequiredFieldLogger');
61
+ const OperationExecutor = require('./OperationExecutor');
62
+ const RelayPublishQueue = require('./RelayPublishQueue');
63
+ const RelayRecordSource = require('./RelayRecordSource');
64
+ const invariant = require('invariant');
65
+
67
66
  export type EnvironmentConfig = {|
68
67
  +configName?: string,
69
68
  +handlerProvider?: ?HandlerProvider,
@@ -228,7 +227,9 @@ class RelayModernEnvironment implements IEnvironment {
228
227
  });
229
228
  }
230
229
 
231
- applyMutation(optimisticConfig: OptimisticResponseConfig): Disposable {
230
+ applyMutation<TMutation: MutationParameters>(
231
+ optimisticConfig: OptimisticResponseConfig<TMutation>,
232
+ ): Disposable {
232
233
  const subscription = this._execute({
233
234
  createSource: () => RelayObservable.create(_sink => {}),
234
235
  isClientPayload: false,
@@ -328,7 +329,7 @@ class RelayModernEnvironment implements IEnvironment {
328
329
 
329
330
  /**
330
331
  * Returns an Observable of GraphQLResponse resulting from executing the
331
- * provided Query or Subscription operation, each result of which is then
332
+ * provided Query operation, each result of which is then
332
333
  * normalized and committed to the publish queue.
333
334
  *
334
335
  * Note: Observables are lazy, so calling this method will do nothing until
@@ -336,10 +337,38 @@ class RelayModernEnvironment implements IEnvironment {
336
337
  */
337
338
  execute({
338
339
  operation,
340
+ }: {|
341
+ operation: OperationDescriptor,
342
+ |}): RelayObservable<GraphQLResponse> {
343
+ return this._execute({
344
+ createSource: () =>
345
+ this._network.execute(
346
+ operation.request.node.params,
347
+ operation.request.variables,
348
+ operation.request.cacheConfig || {},
349
+ null,
350
+ ),
351
+ isClientPayload: false,
352
+ operation,
353
+ optimisticConfig: null,
354
+ updater: null,
355
+ });
356
+ }
357
+
358
+ /**
359
+ * Returns an Observable of GraphQLResponse resulting from executing the
360
+ * provided Subscription operation, each result of which is then
361
+ * normalized and committed to the publish queue.
362
+ *
363
+ * Note: Observables are lazy, so calling this method will do nothing until
364
+ * the result is subscribed to: environment.execute({...}).subscribe({...}).
365
+ */
366
+ executeSubscription<TMutation: MutationParameters>({
367
+ operation,
339
368
  updater,
340
369
  }: {|
341
370
  operation: OperationDescriptor,
342
- updater?: ?SelectorStoreUpdater,
371
+ updater?: ?SelectorStoreUpdater<TMutation['response']>,
343
372
  |}): RelayObservable<GraphQLResponse> {
344
373
  return this._execute({
345
374
  createSource: () =>
@@ -366,13 +395,13 @@ class RelayModernEnvironment implements IEnvironment {
366
395
  * the result is subscribed to:
367
396
  * environment.executeMutation({...}).subscribe({...}).
368
397
  */
369
- executeMutation({
398
+ executeMutation<TMutation: MutationParameters>({
370
399
  operation,
371
400
  optimisticResponse,
372
401
  optimisticUpdater,
373
402
  updater,
374
403
  uploadables,
375
- }: ExecuteMutationConfig): RelayObservable<GraphQLResponse> {
404
+ }: ExecuteMutationConfig<TMutation>): RelayObservable<GraphQLResponse> {
376
405
  let optimisticConfig;
377
406
  if (optimisticResponse || optimisticUpdater) {
378
407
  optimisticConfig = {
@@ -428,7 +457,7 @@ class RelayModernEnvironment implements IEnvironment {
428
457
  return `RelayModernEnvironment(${this.configName ?? ''})`;
429
458
  }
430
459
 
431
- _execute({
460
+ _execute<TMutation: MutationParameters>({
432
461
  createSource,
433
462
  isClientPayload,
434
463
  operation,
@@ -438,8 +467,8 @@ class RelayModernEnvironment implements IEnvironment {
438
467
  createSource: () => RelayObservable<GraphQLResponse>,
439
468
  isClientPayload: boolean,
440
469
  operation: OperationDescriptor,
441
- optimisticConfig: ?OptimisticResponseConfig,
442
- updater: ?SelectorStoreUpdater,
470
+ optimisticConfig: ?OptimisticResponseConfig<TMutation>,
471
+ updater: ?SelectorStoreUpdater<TMutation['response']>,
443
472
  |}): RelayObservable<GraphQLResponse> {
444
473
  const publishQueue = this._publishQueue;
445
474
  const store = this._store;
@@ -12,30 +12,13 @@
12
12
 
13
13
  'use strict';
14
14
 
15
- const RelayFeatureFlags = require('../util/RelayFeatureFlags');
16
-
17
- const areEqual = require('areEqual');
18
- const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
19
- const invariant = require('invariant');
20
- const isScalarAndEqual = require('../util/isScalarAndEqual');
21
- const recycleNodesInto = require('../util/recycleNodesInto');
22
- const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
23
- const warning = require('warning');
24
-
25
- const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
26
- const {
27
- areEqualSelectors,
28
- createReaderSelector,
29
- getSelectorsFromObject,
30
- } = require('./RelayModernSelector');
31
-
32
15
  import type {ConcreteRequest} from '../util/RelayConcreteNode';
33
16
  import type {Disposable, Variables} from '../util/RelayRuntimeTypes';
34
17
  import type {
35
- IEnvironment,
36
18
  FragmentMap,
37
19
  FragmentSpecResolver,
38
20
  FragmentSpecResults,
21
+ IEnvironment,
39
22
  MissingRequiredFields,
40
23
  PluralReaderSelector,
41
24
  RelayContext,
@@ -44,10 +27,25 @@ import type {
44
27
  Snapshot,
45
28
  } from './RelayStoreTypes';
46
29
 
30
+ const getPendingOperationsForFragment = require('../util/getPendingOperationsForFragment');
31
+ const isScalarAndEqual = require('../util/isScalarAndEqual');
32
+ const recycleNodesInto = require('../util/recycleNodesInto');
33
+ const RelayFeatureFlags = require('../util/RelayFeatureFlags');
34
+ const reportMissingRequiredFields = require('../util/reportMissingRequiredFields');
35
+ const {createRequestDescriptor} = require('./RelayModernOperationDescriptor');
36
+ const {
37
+ areEqualSelectors,
38
+ createReaderSelector,
39
+ getSelectorsFromObject,
40
+ } = require('./RelayModernSelector');
41
+ const areEqual = require('areEqual');
42
+ const invariant = require('invariant');
43
+ const warning = require('warning');
44
+
47
45
  type Props = {[key: string]: mixed, ...};
48
46
  type Resolvers = {
49
47
  [key: string]: ?(SelectorListResolver | SelectorResolver),
50
- ...,
48
+ ...
51
49
  };
52
50
 
53
51
  /**