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.
Files changed (219) hide show
  1. package/README.md +67 -0
  2. package/handlers/RelayDefaultHandlerProvider.js.flow +3 -3
  3. package/handlers/connection/ConnectionHandler.js.flow +9 -18
  4. package/handlers/connection/ConnectionInterface.js.flow +1 -1
  5. package/handlers/connection/MutationHandlers.js.flow +8 -12
  6. package/index.js +1 -1
  7. package/index.js.flow +57 -35
  8. package/lib/handlers/RelayDefaultHandlerProvider.js +1 -1
  9. package/lib/handlers/connection/ConnectionHandler.js +13 -19
  10. package/lib/handlers/connection/ConnectionInterface.js +1 -1
  11. package/lib/handlers/connection/MutationHandlers.js +4 -7
  12. package/lib/index.js +59 -44
  13. package/lib/multi-actor-environment/ActorIdentifier.js +12 -2
  14. package/lib/multi-actor-environment/ActorSpecificEnvironment.js +64 -20
  15. package/lib/multi-actor-environment/ActorUtils.js +27 -0
  16. package/lib/multi-actor-environment/MultiActorEnvironment.js +324 -61
  17. package/lib/multi-actor-environment/MultiActorEnvironmentTypes.js +1 -1
  18. package/lib/multi-actor-environment/index.js +6 -2
  19. package/lib/mutations/RelayDeclarativeMutationConfig.js +5 -2
  20. package/lib/mutations/RelayRecordProxy.js +4 -3
  21. package/lib/mutations/RelayRecordSourceMutator.js +4 -3
  22. package/lib/mutations/RelayRecordSourceProxy.js +13 -5
  23. package/lib/mutations/RelayRecordSourceSelectorProxy.js +19 -6
  24. package/lib/mutations/applyOptimisticMutation.js +7 -7
  25. package/lib/mutations/commitLocalUpdate.js +1 -1
  26. package/lib/mutations/commitMutation.js +15 -11
  27. package/lib/mutations/readUpdatableQuery_EXPERIMENTAL.js +242 -0
  28. package/lib/mutations/validateMutation.js +11 -6
  29. package/lib/network/ConvertToExecuteFunction.js +3 -2
  30. package/lib/network/RelayNetwork.js +4 -3
  31. package/lib/network/RelayNetworkTypes.js +1 -1
  32. package/lib/network/RelayObservable.js +1 -1
  33. package/lib/network/RelayQueryResponseCache.js +22 -6
  34. package/lib/network/wrapNetworkWithLogObserver.js +79 -0
  35. package/lib/query/GraphQLTag.js +3 -2
  36. package/lib/query/PreloadableQueryRegistry.js +1 -1
  37. package/lib/query/fetchQuery.js +7 -6
  38. package/lib/query/fetchQueryInternal.js +1 -1
  39. package/lib/query/fetchQuery_DEPRECATED.js +3 -2
  40. package/lib/store/ClientID.js +8 -2
  41. package/lib/store/DataChecker.js +124 -55
  42. package/lib/store/OperationExecutor.js +489 -215
  43. package/lib/store/RelayConcreteVariables.js +27 -9
  44. package/lib/store/RelayExperimentalGraphResponseHandler.js +153 -0
  45. package/lib/store/RelayExperimentalGraphResponseTransform.js +391 -0
  46. package/lib/store/RelayModernEnvironment.js +100 -120
  47. package/lib/store/RelayModernFragmentSpecResolver.js +53 -27
  48. package/lib/store/RelayModernOperationDescriptor.js +3 -2
  49. package/lib/store/RelayModernRecord.js +48 -13
  50. package/lib/store/RelayModernSelector.js +15 -9
  51. package/lib/store/RelayModernStore.js +56 -23
  52. package/lib/store/RelayOperationTracker.js +34 -24
  53. package/lib/store/RelayOptimisticRecordSource.js +1 -1
  54. package/lib/store/RelayPublishQueue.js +35 -11
  55. package/lib/store/RelayReader.js +257 -72
  56. package/lib/store/RelayRecordSource.js +88 -4
  57. package/lib/store/RelayRecordState.js +1 -1
  58. package/lib/store/RelayReferenceMarker.js +34 -22
  59. package/lib/store/RelayResponseNormalizer.js +172 -96
  60. package/lib/store/RelayStoreReactFlightUtils.js +5 -11
  61. package/lib/store/RelayStoreSubscriptions.js +15 -10
  62. package/lib/store/RelayStoreTypes.js +1 -1
  63. package/lib/store/RelayStoreUtils.js +13 -8
  64. package/lib/store/ResolverCache.js +213 -0
  65. package/lib/store/ResolverFragments.js +10 -6
  66. package/lib/store/StoreInspector.js +1 -1
  67. package/lib/store/TypeID.js +1 -1
  68. package/lib/store/ViewerPattern.js +1 -1
  69. package/lib/store/cloneRelayHandleSourceField.js +6 -5
  70. package/lib/store/cloneRelayScalarHandleSourceField.js +6 -5
  71. package/lib/store/createFragmentSpecResolver.js +1 -1
  72. package/lib/store/createRelayContext.js +5 -3
  73. package/lib/store/defaultGetDataID.js +1 -1
  74. package/lib/store/defaultRequiredFieldLogger.js +1 -1
  75. package/lib/store/hasOverlappingIDs.js +1 -1
  76. package/lib/store/isRelayModernEnvironment.js +1 -1
  77. package/lib/store/normalizeRelayPayload.js +1 -1
  78. package/lib/store/readInlineData.js +7 -3
  79. package/lib/subscription/requestSubscription.js +32 -34
  80. package/lib/util/JSResourceTypes.flow.js +1 -1
  81. package/lib/util/NormalizationNode.js +1 -1
  82. package/lib/util/ReaderNode.js +1 -1
  83. package/lib/util/RelayConcreteNode.js +3 -1
  84. package/lib/util/RelayDefaultHandleKey.js +1 -1
  85. package/lib/util/RelayError.js +1 -1
  86. package/lib/util/RelayFeatureFlags.js +10 -7
  87. package/lib/util/RelayProfiler.js +1 -1
  88. package/lib/util/RelayReplaySubject.js +22 -7
  89. package/lib/util/RelayRuntimeTypes.js +1 -7
  90. package/lib/util/StringInterner.js +71 -0
  91. package/lib/util/createPayloadFor3DField.js +1 -1
  92. package/lib/util/deepFreeze.js +1 -1
  93. package/lib/util/generateID.js +1 -1
  94. package/lib/util/getAllRootVariables.js +29 -0
  95. package/lib/util/getFragmentIdentifier.js +16 -8
  96. package/lib/util/getOperation.js +3 -2
  97. package/lib/util/getPaginationMetadata.js +41 -0
  98. package/lib/util/getPaginationVariables.js +66 -0
  99. package/lib/util/getPendingOperationsForFragment.js +55 -0
  100. package/lib/util/getRefetchMetadata.js +36 -0
  101. package/lib/util/getRelayHandleKey.js +3 -3
  102. package/lib/util/getRequestIdentifier.js +3 -3
  103. package/lib/util/getValueAtPath.js +51 -0
  104. package/lib/util/isEmptyObject.js +2 -2
  105. package/lib/util/isPromise.js +1 -1
  106. package/lib/util/isScalarAndEqual.js +1 -1
  107. package/lib/util/recycleNodesInto.js +1 -1
  108. package/lib/util/registerEnvironmentWithDevTools.js +26 -0
  109. package/lib/util/reportMissingRequiredFields.js +1 -1
  110. package/lib/util/resolveImmediate.js +1 -1
  111. package/lib/util/stableCopy.js +1 -1
  112. package/lib/util/withDuration.js +31 -0
  113. package/multi-actor-environment/ActorIdentifier.js.flow +18 -2
  114. package/multi-actor-environment/ActorSpecificEnvironment.js.flow +94 -58
  115. package/multi-actor-environment/ActorUtils.js.flow +33 -0
  116. package/multi-actor-environment/MultiActorEnvironment.js.flow +366 -93
  117. package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +88 -23
  118. package/multi-actor-environment/index.js.flow +3 -1
  119. package/mutations/RelayDeclarativeMutationConfig.js.flow +33 -27
  120. package/mutations/RelayRecordProxy.js.flow +5 -6
  121. package/mutations/RelayRecordSourceMutator.js.flow +5 -7
  122. package/mutations/RelayRecordSourceProxy.js.flow +20 -11
  123. package/mutations/RelayRecordSourceSelectorProxy.js.flow +23 -8
  124. package/mutations/applyOptimisticMutation.js.flow +14 -15
  125. package/mutations/commitLocalUpdate.js.flow +2 -2
  126. package/mutations/commitMutation.js.flow +36 -47
  127. package/mutations/readUpdatableQuery_EXPERIMENTAL.js.flow +318 -0
  128. package/mutations/validateMutation.js.flow +27 -17
  129. package/network/ConvertToExecuteFunction.js.flow +3 -3
  130. package/network/RelayNetwork.js.flow +5 -6
  131. package/network/RelayNetworkTypes.js.flow +1 -1
  132. package/network/RelayObservable.js.flow +2 -2
  133. package/network/RelayQueryResponseCache.js.flow +35 -22
  134. package/network/wrapNetworkWithLogObserver.js.flow +99 -0
  135. package/package.json +2 -2
  136. package/query/GraphQLTag.js.flow +11 -11
  137. package/query/PreloadableQueryRegistry.js.flow +5 -3
  138. package/query/fetchQuery.js.flow +19 -19
  139. package/query/fetchQueryInternal.js.flow +7 -10
  140. package/query/fetchQuery_DEPRECATED.js.flow +7 -7
  141. package/relay-runtime.js +2 -2
  142. package/relay-runtime.min.js +2 -2
  143. package/store/ClientID.js.flow +15 -4
  144. package/store/DataChecker.js.flow +142 -60
  145. package/store/OperationExecutor.js.flow +575 -320
  146. package/store/RelayConcreteVariables.js.flow +28 -9
  147. package/store/RelayExperimentalGraphResponseHandler.js.flow +121 -0
  148. package/store/RelayExperimentalGraphResponseTransform.js.flow +470 -0
  149. package/store/RelayModernEnvironment.js.flow +91 -115
  150. package/store/RelayModernFragmentSpecResolver.js.flow +56 -32
  151. package/store/RelayModernOperationDescriptor.js.flow +13 -8
  152. package/store/RelayModernRecord.js.flow +68 -12
  153. package/store/RelayModernSelector.js.flow +25 -15
  154. package/store/RelayModernStore.js.flow +67 -32
  155. package/store/RelayOperationTracker.js.flow +60 -44
  156. package/store/RelayOptimisticRecordSource.js.flow +3 -3
  157. package/store/RelayPublishQueue.js.flow +74 -32
  158. package/store/RelayReader.js.flow +319 -100
  159. package/store/RelayRecordSource.js.flow +73 -7
  160. package/store/RelayRecordState.js.flow +1 -1
  161. package/store/RelayReferenceMarker.js.flow +41 -27
  162. package/store/RelayResponseNormalizer.js.flow +204 -86
  163. package/store/RelayStoreReactFlightUtils.js.flow +5 -12
  164. package/store/RelayStoreSubscriptions.js.flow +20 -12
  165. package/store/RelayStoreTypes.js.flow +200 -41
  166. package/store/RelayStoreUtils.js.flow +25 -12
  167. package/store/ResolverCache.js.flow +249 -0
  168. package/store/ResolverFragments.js.flow +16 -20
  169. package/store/StoreInspector.js.flow +3 -3
  170. package/store/TypeID.js.flow +2 -2
  171. package/store/ViewerPattern.js.flow +3 -3
  172. package/store/cloneRelayHandleSourceField.js.flow +6 -7
  173. package/store/cloneRelayScalarHandleSourceField.js.flow +6 -7
  174. package/store/createFragmentSpecResolver.js.flow +4 -5
  175. package/store/createRelayContext.js.flow +4 -4
  176. package/store/defaultGetDataID.js.flow +1 -1
  177. package/store/defaultRequiredFieldLogger.js.flow +1 -1
  178. package/store/hasOverlappingIDs.js.flow +1 -1
  179. package/store/isRelayModernEnvironment.js.flow +1 -1
  180. package/store/normalizeRelayPayload.js.flow +7 -8
  181. package/store/readInlineData.js.flow +8 -9
  182. package/subscription/requestSubscription.js.flow +55 -51
  183. package/util/JSResourceTypes.flow.js.flow +1 -1
  184. package/util/NormalizationNode.js.flow +11 -4
  185. package/util/ReaderNode.js.flow +25 -2
  186. package/util/RelayConcreteNode.js.flow +5 -1
  187. package/util/RelayDefaultHandleKey.js.flow +1 -1
  188. package/util/RelayError.js.flow +1 -1
  189. package/util/RelayFeatureFlags.js.flow +23 -15
  190. package/util/RelayProfiler.js.flow +1 -1
  191. package/util/RelayReplaySubject.js.flow +10 -10
  192. package/util/RelayRuntimeTypes.js.flow +70 -3
  193. package/util/StringInterner.js.flow +69 -0
  194. package/util/createPayloadFor3DField.js.flow +4 -4
  195. package/util/deepFreeze.js.flow +1 -1
  196. package/util/generateID.js.flow +1 -1
  197. package/util/getAllRootVariables.js.flow +36 -0
  198. package/util/getFragmentIdentifier.js.flow +28 -16
  199. package/util/getOperation.js.flow +3 -3
  200. package/util/getPaginationMetadata.js.flow +69 -0
  201. package/util/getPaginationVariables.js.flow +108 -0
  202. package/util/getPendingOperationsForFragment.js.flow +62 -0
  203. package/util/getRefetchMetadata.js.flow +76 -0
  204. package/util/getRelayHandleKey.js.flow +2 -3
  205. package/util/getRequestIdentifier.js.flow +4 -4
  206. package/util/getValueAtPath.js.flow +46 -0
  207. package/util/isEmptyObject.js.flow +2 -1
  208. package/util/isPromise.js.flow +1 -1
  209. package/util/isScalarAndEqual.js.flow +1 -1
  210. package/util/recycleNodesInto.js.flow +1 -1
  211. package/util/registerEnvironmentWithDevTools.js.flow +33 -0
  212. package/util/reportMissingRequiredFields.js.flow +1 -1
  213. package/util/resolveImmediate.js.flow +2 -2
  214. package/util/stableCopy.js.flow +1 -1
  215. package/util/withDuration.js.flow +32 -0
  216. package/lib/store/RelayRecordSourceMapImpl.js +0 -107
  217. package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
  218. package/store/RelayRecordSourceMapImpl.js.flow +0 -91
  219. package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
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
- 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
  }
@@ -40,4 +47,8 @@ function generateUniqueClientID(): DataID {
40
47
  return `${PREFIX}local:${localID++}`;
41
48
  }
42
49
 
43
- module.exports = {generateClientID, generateUniqueClientID, isClientID};
50
+ module.exports = {
51
+ generateClientID,
52
+ generateUniqueClientID,
53
+ isClientID,
54
+ };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
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,23 +13,7 @@
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 {EXISTENT, UNKNOWN} = require('./RelayRecordState');
31
- const {generateTypeID} = require('./TypeID');
32
-
16
+ import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
33
17
  import type {
34
18
  NormalizationField,
35
19
  NormalizationFlightField,
@@ -51,12 +35,29 @@ import type {
51
35
  RecordSource,
52
36
  } from './RelayStoreTypes';
53
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
+
54
54
  export type Availability = {|
55
55
  +status: 'available' | 'missing',
56
56
  +mostRecentlyInvalidatedAt: ?number,
57
57
  |};
58
58
 
59
59
  const {
60
+ ACTOR_CHANGE,
60
61
  CONDITION,
61
62
  CLIENT_COMPONENT,
62
63
  CLIENT_EXTENSION,
@@ -72,12 +73,8 @@ const {
72
73
  STREAM,
73
74
  TYPE_DISCRIMINATOR,
74
75
  } = RelayConcreteNode;
75
- const {
76
- ROOT_ID,
77
- getModuleOperationKey,
78
- getStorageKey,
79
- getArgumentValues,
80
- } = RelayStoreUtils;
76
+ const {ROOT_ID, getModuleOperationKey, getStorageKey, getArgumentValues} =
77
+ RelayStoreUtils;
81
78
 
82
79
  /**
83
80
  * Synchronously check whether the records required to fulfill the given
@@ -90,8 +87,9 @@ const {
90
87
  * If all records are present, returns `true`, otherwise `false`.
91
88
  */
92
89
  function check(
93
- source: RecordSource,
94
- target: MutableRecordSource,
90
+ getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource,
91
+ getTargetForActor: (actorIdentifier: ActorIdentifier) => MutableRecordSource,
92
+ defaultActorIdentifier: ActorIdentifier,
95
93
  selector: NormalizationSelector,
96
94
  handlers: $ReadOnlyArray<MissingFieldHandler>,
97
95
  operationLoader: ?OperationLoader,
@@ -100,8 +98,9 @@ function check(
100
98
  ): Availability {
101
99
  const {dataID, node, variables} = selector;
102
100
  const checker = new DataChecker(
103
- source,
104
- target,
101
+ getSourceForActor,
102
+ getTargetForActor,
103
+ defaultActorIdentifier,
105
104
  variables,
106
105
  handlers,
107
106
  operationLoader,
@@ -125,28 +124,67 @@ class DataChecker {
125
124
  _source: RecordSource;
126
125
  _variables: Variables;
127
126
  _shouldProcessClientComponents: ?boolean;
127
+ +_getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource;
128
+ +_getTargetForActor: (
129
+ actorIdentifier: ActorIdentifier,
130
+ ) => MutableRecordSource;
131
+ +_getDataID: GetDataID;
132
+ +_mutatorRecordSourceProxyCache: Map<
133
+ ActorIdentifier,
134
+ [RelayRecordSourceMutator, RelayRecordSourceProxy],
135
+ >;
128
136
 
129
137
  constructor(
130
- source: RecordSource,
131
- target: MutableRecordSource,
138
+ getSourceForActor: (actorIdentifier: ActorIdentifier) => RecordSource,
139
+ getTargetForActor: (
140
+ actorIdentifier: ActorIdentifier,
141
+ ) => MutableRecordSource,
142
+ defaultActorIdentifier: ActorIdentifier,
132
143
  variables: Variables,
133
144
  handlers: $ReadOnlyArray<MissingFieldHandler>,
134
145
  operationLoader: ?OperationLoader,
135
146
  getDataID: GetDataID,
136
147
  shouldProcessClientComponents: ?boolean,
137
148
  ) {
138
- const mutator = new RelayRecordSourceMutator(source, target);
149
+ this._getSourceForActor = getSourceForActor;
150
+ this._getTargetForActor = getTargetForActor;
151
+ this._getDataID = getDataID;
152
+ this._source = getSourceForActor(defaultActorIdentifier);
153
+ this._mutatorRecordSourceProxyCache = new Map();
154
+ const [mutator, recordSourceProxy] = this._getMutatorAndRecordProxyForActor(
155
+ defaultActorIdentifier,
156
+ );
139
157
  this._mostRecentlyInvalidatedAt = null;
140
158
  this._handlers = handlers;
141
159
  this._mutator = mutator;
142
160
  this._operationLoader = operationLoader ?? null;
143
- this._recordSourceProxy = new RelayRecordSourceProxy(mutator, getDataID);
161
+ this._recordSourceProxy = recordSourceProxy;
144
162
  this._recordWasMissing = false;
145
- this._source = source;
146
163
  this._variables = variables;
147
164
  this._shouldProcessClientComponents = shouldProcessClientComponents;
148
165
  }
149
166
 
167
+ _getMutatorAndRecordProxyForActor(
168
+ actorIdentifier: ActorIdentifier,
169
+ ): [RelayRecordSourceMutator, RelayRecordSourceProxy] {
170
+ let tuple = this._mutatorRecordSourceProxyCache.get(actorIdentifier);
171
+ if (tuple == null) {
172
+ const target = this._getTargetForActor(actorIdentifier);
173
+
174
+ const mutator = new RelayRecordSourceMutator(
175
+ this._getSourceForActor(actorIdentifier),
176
+ target,
177
+ );
178
+ const recordSourceProxy = new RelayRecordSourceProxy(
179
+ mutator,
180
+ this._getDataID,
181
+ );
182
+ tuple = [mutator, recordSourceProxy];
183
+ this._mutatorRecordSourceProxyCache.set(actorIdentifier, tuple);
184
+ }
185
+ return tuple;
186
+ }
187
+
150
188
  check(node: NormalizationNode, dataID: DataID): Availability {
151
189
  this._traverse(node, dataID);
152
190
 
@@ -167,7 +205,6 @@ class DataChecker {
167
205
  'RelayAsyncLoader(): Undefined variable `%s`.',
168
206
  name,
169
207
  );
170
- // $FlowFixMe[cannot-write]
171
208
  return this._variables[name];
172
209
  }
173
210
 
@@ -184,6 +221,8 @@ class DataChecker {
184
221
  ...
185
222
  } {
186
223
  return {
224
+ /* $FlowFixMe[class-object-subtyping] added when improving typing for
225
+ * this parameters */
187
226
  args: field.args ? getArgumentValues(field.args, this._variables) : {},
188
227
  // Getting a snapshot of the record state is potentially expensive since
189
228
  // we will need to merge the sink and source records. Since we do not create
@@ -309,8 +348,13 @@ class DataChecker {
309
348
  this._checkLink(selection, dataID);
310
349
  }
311
350
  break;
351
+ case ACTOR_CHANGE:
352
+ this._checkActorChange(selection.linkedField, dataID);
353
+ break;
312
354
  case CONDITION:
313
- const conditionValue = this._getVariableValue(selection.condition);
355
+ const conditionValue = Boolean(
356
+ this._getVariableValue(selection.condition),
357
+ );
314
358
  if (conditionValue === selection.passingValue) {
315
359
  this._traverseSelections(selection.selections, dataID);
316
360
  }
@@ -323,7 +367,7 @@ class DataChecker {
323
367
  if (typeName === selection.type) {
324
368
  this._traverseSelections(selection.selections, dataID);
325
369
  }
326
- } else if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
370
+ } else {
327
371
  // Abstract refinement: check data depending on whether the type
328
372
  // conforms to the interface/union or not:
329
373
  // - Type known to _not_ implement the interface: don't check the selections.
@@ -349,10 +393,6 @@ class DataChecker {
349
393
  // missing so don't bother reading the fragment
350
394
  this._handleMissing();
351
395
  } // else false: known to not implement the interface
352
- } else {
353
- // legacy behavior for abstract refinements: always check even
354
- // if the type doesn't conform
355
- this._traverseSelections(selection.selections, dataID);
356
396
  }
357
397
  break;
358
398
  }
@@ -388,9 +428,15 @@ class DataChecker {
388
428
  case STREAM:
389
429
  this._traverseSelections(selection.selections, dataID);
390
430
  break;
391
- // $FlowFixMe[incompatible-type]
392
431
  case FRAGMENT_SPREAD:
432
+ const prevVariables = this._variables;
433
+ this._variables = getLocalVariables(
434
+ this._variables,
435
+ selection.fragment.argumentDefinitions,
436
+ selection.args,
437
+ );
393
438
  this._traverseSelections(selection.fragment.selections, dataID);
439
+ this._variables = prevVariables;
394
440
  break;
395
441
  case CLIENT_EXTENSION:
396
442
  const recordWasMissing = this._recordWasMissing;
@@ -398,25 +444,23 @@ class DataChecker {
398
444
  this._recordWasMissing = recordWasMissing;
399
445
  break;
400
446
  case TYPE_DISCRIMINATOR:
401
- if (RelayFeatureFlags.ENABLE_PRECISE_TYPE_REFINEMENT) {
402
- const {abstractKey} = selection;
403
- const recordType = this._mutator.getType(dataID);
404
- invariant(
405
- recordType != null,
406
- 'DataChecker: Expected record `%s` to have a known type',
407
- dataID,
408
- );
409
- const typeID = generateTypeID(recordType);
410
- const implementsInterface = this._mutator.getValue(
411
- typeID,
412
- abstractKey,
413
- );
414
- if (implementsInterface == null) {
415
- // unsure if the type implements the interface: data is
416
- // missing
417
- this._handleMissing();
418
- } // else: if it does or doesn't implement, we don't need to check or skip anything else
419
- }
447
+ const {abstractKey} = selection;
448
+ const recordType = this._mutator.getType(dataID);
449
+ invariant(
450
+ recordType != null,
451
+ 'DataChecker: Expected record `%s` to have a known type',
452
+ dataID,
453
+ );
454
+ const typeID = generateTypeID(recordType);
455
+ const implementsInterface = this._mutator.getValue(
456
+ typeID,
457
+ abstractKey,
458
+ );
459
+ if (implementsInterface == null) {
460
+ // unsure if the type implements the interface: data is
461
+ // missing
462
+ this._handleMissing();
463
+ } // else: if it does or doesn't implement, we don't need to check or skip anything else
420
464
  break;
421
465
  case FLIGHT_FIELD:
422
466
  if (RelayFeatureFlags.ENABLE_REACT_FLIGHT_COMPONENT_FIELD) {
@@ -462,7 +506,14 @@ class DataChecker {
462
506
  const normalizationRootNode = operationLoader.get(operationReference);
463
507
  if (normalizationRootNode != null) {
464
508
  const operation = getOperation(normalizationRootNode);
509
+ const prevVariables = this._variables;
510
+ this._variables = getLocalVariables(
511
+ this._variables,
512
+ operation.argumentDefinitions,
513
+ moduleImport.args,
514
+ );
465
515
  this._traverse(operation, dataID);
516
+ this._variables = prevVariables;
466
517
  } else {
467
518
  // If the fragment is not available, we assume that the data cannot have been
468
519
  // processed yet and must therefore be missing.
@@ -519,6 +570,37 @@ class DataChecker {
519
570
  }
520
571
  }
521
572
 
573
+ _checkActorChange(field: NormalizationLinkedField, dataID: DataID): void {
574
+ const storageKey = getStorageKey(field, this._variables);
575
+ const record = this._source.get(dataID);
576
+ const tuple =
577
+ record != null
578
+ ? RelayModernRecord.getActorLinkedRecordID(record, storageKey)
579
+ : record;
580
+
581
+ if (tuple == null) {
582
+ if (tuple === undefined) {
583
+ this._handleMissing();
584
+ }
585
+ } else {
586
+ const [actorIdentifier, linkedID] = tuple;
587
+ const prevSource = this._source;
588
+ const prevMutator = this._mutator;
589
+ const prevRecordSourceProxy = this._recordSourceProxy;
590
+
591
+ const [mutator, recordSourceProxy] =
592
+ this._getMutatorAndRecordProxyForActor(actorIdentifier);
593
+
594
+ this._source = this._getSourceForActor(actorIdentifier);
595
+ this._mutator = mutator;
596
+ this._recordSourceProxy = recordSourceProxy;
597
+ this._traverse(field, linkedID);
598
+ this._source = prevSource;
599
+ this._mutator = prevMutator;
600
+ this._recordSourceProxy = prevRecordSourceProxy;
601
+ }
602
+ }
603
+
522
604
  _checkFlightField(field: NormalizationFlightField, dataID: DataID): void {
523
605
  const storageKey = getStorageKey(field, this._variables);
524
606
  const linkedID = this._mutator.getLinkedRecordID(dataID, storageKey);