relay-runtime 11.0.2 → 12.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/index.js +1 -1
- package/index.js.flow +16 -1
- package/lib/index.js +15 -0
- package/lib/multi-actor-environment/ActorIdentifier.js +11 -1
- package/lib/multi-actor-environment/ActorSpecificEnvironment.js +59 -19
- package/lib/multi-actor-environment/ActorUtils.js +27 -0
- package/lib/multi-actor-environment/MultiActorEnvironment.js +305 -55
- package/lib/multi-actor-environment/index.js +5 -1
- package/lib/mutations/RelayRecordSourceSelectorProxy.js +6 -1
- package/lib/mutations/commitMutation.js +4 -1
- package/lib/mutations/validateMutation.js +6 -1
- package/lib/network/RelayObservable.js +3 -1
- package/lib/network/RelayQueryResponseCache.js +19 -3
- package/lib/network/wrapNetworkWithLogObserver.js +78 -0
- package/lib/store/DataChecker.js +110 -40
- package/lib/store/OperationExecutor.js +478 -204
- package/lib/store/RelayConcreteVariables.js +21 -0
- package/lib/store/RelayModernEnvironment.js +41 -85
- package/lib/store/RelayModernFragmentSpecResolver.js +48 -22
- package/lib/store/RelayModernRecord.js +35 -1
- package/lib/store/RelayModernStore.js +48 -14
- package/lib/store/RelayOperationTracker.js +33 -23
- package/lib/store/RelayPublishQueue.js +23 -5
- package/lib/store/RelayReader.js +138 -44
- package/lib/store/RelayRecordSource.js +87 -3
- package/lib/store/RelayReferenceMarker.js +28 -15
- package/lib/store/RelayResponseNormalizer.js +164 -91
- package/lib/store/RelayStoreReactFlightUtils.js +1 -7
- package/lib/store/RelayStoreSubscriptions.js +8 -5
- package/lib/store/RelayStoreUtils.js +7 -2
- package/lib/store/ResolverCache.js +213 -0
- package/lib/store/ResolverFragments.js +1 -1
- package/lib/store/createRelayContext.js +1 -1
- package/lib/subscription/requestSubscription.js +27 -29
- package/lib/util/RelayConcreteNode.js +1 -0
- package/lib/util/RelayFeatureFlags.js +3 -5
- package/lib/util/RelayReplaySubject.js +21 -6
- package/lib/util/getPaginationMetadata.js +41 -0
- package/lib/util/getPaginationVariables.js +67 -0
- package/lib/util/getPendingOperationsForFragment.js +55 -0
- package/lib/util/getRefetchMetadata.js +36 -0
- package/lib/util/getValueAtPath.js +51 -0
- package/lib/util/isEmptyObject.js +1 -1
- package/lib/util/registerEnvironmentWithDevTools.js +26 -0
- package/lib/util/withDuration.js +31 -0
- package/multi-actor-environment/ActorIdentifier.js.flow +17 -1
- package/multi-actor-environment/ActorSpecificEnvironment.js.flow +72 -44
- package/multi-actor-environment/ActorUtils.js.flow +33 -0
- package/multi-actor-environment/MultiActorEnvironment.js.flow +332 -80
- package/multi-actor-environment/MultiActorEnvironmentTypes.js.flow +61 -12
- package/multi-actor-environment/index.js.flow +3 -0
- package/mutations/RelayRecordSourceSelectorProxy.js.flow +7 -2
- package/mutations/commitMutation.js.flow +2 -0
- package/mutations/validateMutation.js.flow +8 -0
- package/network/RelayObservable.js.flow +2 -0
- package/network/RelayQueryResponseCache.js.flow +31 -18
- package/network/wrapNetworkWithLogObserver.js.flow +99 -0
- package/package.json +1 -1
- package/relay-runtime.js +2 -2
- package/relay-runtime.min.js +2 -2
- package/store/ClientID.js.flow +5 -1
- package/store/DataChecker.js.flow +126 -35
- package/store/OperationExecutor.js.flow +528 -265
- package/store/RelayConcreteVariables.js.flow +26 -1
- package/store/RelayModernEnvironment.js.flow +41 -94
- package/store/RelayModernFragmentSpecResolver.js.flow +40 -14
- package/store/RelayModernOperationDescriptor.js.flow +9 -3
- package/store/RelayModernRecord.js.flow +49 -0
- package/store/RelayModernStore.js.flow +50 -12
- package/store/RelayOperationTracker.js.flow +56 -34
- package/store/RelayPublishQueue.js.flow +31 -8
- package/store/RelayReader.js.flow +148 -42
- package/store/RelayRecordSource.js.flow +72 -6
- package/store/RelayReferenceMarker.js.flow +29 -12
- package/store/RelayResponseNormalizer.js.flow +164 -48
- package/store/RelayStoreReactFlightUtils.js.flow +1 -7
- package/store/RelayStoreSubscriptions.js.flow +10 -3
- package/store/RelayStoreTypes.js.flow +128 -12
- package/store/RelayStoreUtils.js.flow +17 -3
- package/store/ResolverCache.js.flow +247 -0
- package/store/ResolverFragments.js.flow +6 -3
- package/store/createRelayContext.js.flow +1 -1
- package/subscription/requestSubscription.js.flow +41 -29
- package/util/NormalizationNode.js.flow +10 -3
- package/util/ReaderNode.js.flow +15 -1
- package/util/RelayConcreteNode.js.flow +1 -0
- package/util/RelayFeatureFlags.js.flow +8 -10
- package/util/RelayReplaySubject.js.flow +7 -6
- package/util/getPaginationMetadata.js.flow +74 -0
- package/util/getPaginationVariables.js.flow +112 -0
- package/util/getPendingOperationsForFragment.js.flow +62 -0
- package/util/getRefetchMetadata.js.flow +80 -0
- package/util/getValueAtPath.js.flow +46 -0
- package/util/isEmptyObject.js.flow +1 -0
- package/util/registerEnvironmentWithDevTools.js.flow +33 -0
- package/util/withDuration.js.flow +32 -0
- package/lib/store/RelayRecordSourceMapImpl.js +0 -107
- package/lib/store/RelayStoreSubscriptionsUsingMapByID.js +0 -318
- package/store/RelayRecordSourceMapImpl.js.flow +0 -91
- package/store/RelayStoreSubscriptionsUsingMapByID.js.flow +0 -283
|
@@ -22,6 +22,7 @@ const cloneRelayHandleSourceField = require('./cloneRelayHandleSourceField');
|
|
|
22
22
|
const getOperation = require('../util/getOperation');
|
|
23
23
|
const invariant = require('invariant');
|
|
24
24
|
|
|
25
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
25
26
|
const {generateTypeID} = require('./TypeID');
|
|
26
27
|
|
|
27
28
|
import type {
|
|
@@ -42,6 +43,7 @@ import type {
|
|
|
42
43
|
} from './RelayStoreTypes';
|
|
43
44
|
|
|
44
45
|
const {
|
|
46
|
+
ACTOR_CHANGE,
|
|
45
47
|
CONDITION,
|
|
46
48
|
CLIENT_COMPONENT,
|
|
47
49
|
CLIENT_EXTENSION,
|
|
@@ -136,6 +138,10 @@ class RelayReferenceMarker {
|
|
|
136
138
|
selections.forEach(selection => {
|
|
137
139
|
/* eslint-disable no-fallthrough */
|
|
138
140
|
switch (selection.kind) {
|
|
141
|
+
case ACTOR_CHANGE:
|
|
142
|
+
// TODO: T89695151 Support multi-actor record sources in RelayReferenceMarker.js
|
|
143
|
+
this._traverseLink(selection.linkedField, record);
|
|
144
|
+
break;
|
|
139
145
|
case LINKED_FIELD:
|
|
140
146
|
if (selection.plural) {
|
|
141
147
|
this._traversePluralLink(selection, record);
|
|
@@ -144,7 +150,9 @@ class RelayReferenceMarker {
|
|
|
144
150
|
}
|
|
145
151
|
break;
|
|
146
152
|
case CONDITION:
|
|
147
|
-
const conditionValue =
|
|
153
|
+
const conditionValue = Boolean(
|
|
154
|
+
this._getVariableValue(selection.condition),
|
|
155
|
+
);
|
|
148
156
|
if (conditionValue === selection.passingValue) {
|
|
149
157
|
this._traverseSelections(selection.selections, record);
|
|
150
158
|
}
|
|
@@ -155,18 +163,22 @@ class RelayReferenceMarker {
|
|
|
155
163
|
if (typeName != null && typeName === selection.type) {
|
|
156
164
|
this._traverseSelections(selection.selections, record);
|
|
157
165
|
}
|
|
158
|
-
} else
|
|
166
|
+
} else {
|
|
159
167
|
const typeName = RelayModernRecord.getType(record);
|
|
160
168
|
const typeID = generateTypeID(typeName);
|
|
161
169
|
this._references.add(typeID);
|
|
162
170
|
this._traverseSelections(selection.selections, record);
|
|
163
|
-
} else {
|
|
164
|
-
this._traverseSelections(selection.selections, record);
|
|
165
171
|
}
|
|
166
172
|
break;
|
|
167
|
-
// $FlowFixMe[incompatible-type]
|
|
168
173
|
case FRAGMENT_SPREAD:
|
|
174
|
+
const prevVariables = this._variables;
|
|
175
|
+
this._variables = getLocalVariables(
|
|
176
|
+
this._variables,
|
|
177
|
+
selection.fragment.argumentDefinitions,
|
|
178
|
+
selection.args,
|
|
179
|
+
);
|
|
169
180
|
this._traverseSelections(selection.fragment.selections, record);
|
|
181
|
+
this._variables = prevVariables;
|
|
170
182
|
break;
|
|
171
183
|
case LINKED_HANDLE:
|
|
172
184
|
// The selections for a "handle" field are the same as those of the
|
|
@@ -197,11 +209,9 @@ class RelayReferenceMarker {
|
|
|
197
209
|
case SCALAR_HANDLE:
|
|
198
210
|
break;
|
|
199
211
|
case TYPE_DISCRIMINATOR: {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
this._references.add(typeID);
|
|
204
|
-
}
|
|
212
|
+
const typeName = RelayModernRecord.getType(record);
|
|
213
|
+
const typeID = generateTypeID(typeName);
|
|
214
|
+
this._references.add(typeID);
|
|
205
215
|
break;
|
|
206
216
|
}
|
|
207
217
|
case MODULE_IMPORT:
|
|
@@ -253,8 +263,15 @@ class RelayReferenceMarker {
|
|
|
253
263
|
}
|
|
254
264
|
const normalizationRootNode = operationLoader.get(operationReference);
|
|
255
265
|
if (normalizationRootNode != null) {
|
|
256
|
-
const
|
|
257
|
-
this.
|
|
266
|
+
const operation = getOperation(normalizationRootNode);
|
|
267
|
+
const prevVariables = this._variables;
|
|
268
|
+
this._variables = getLocalVariables(
|
|
269
|
+
this._variables,
|
|
270
|
+
operation.argumentDefinitions,
|
|
271
|
+
moduleImport.args,
|
|
272
|
+
);
|
|
273
|
+
this._traverseSelections(operation.selections, record);
|
|
274
|
+
this._variables = prevVariables;
|
|
258
275
|
}
|
|
259
276
|
// Otherwise, if the operation is not available, we assume that the data
|
|
260
277
|
// cannot have been processed yet and therefore isn't in the store to
|
|
@@ -20,6 +20,11 @@ const invariant = require('invariant');
|
|
|
20
20
|
const warning = require('warning');
|
|
21
21
|
|
|
22
22
|
const {
|
|
23
|
+
ACTOR_IDENTIFIER_FIELD_NAME,
|
|
24
|
+
getActorIdentifierFromPayload,
|
|
25
|
+
} = require('../multi-actor-environment/ActorUtils');
|
|
26
|
+
const {
|
|
27
|
+
ACTOR_CHANGE,
|
|
23
28
|
CONDITION,
|
|
24
29
|
CLIENT_COMPONENT,
|
|
25
30
|
CLIENT_EXTENSION,
|
|
@@ -36,6 +41,7 @@ const {
|
|
|
36
41
|
TYPE_DISCRIMINATOR,
|
|
37
42
|
} = require('../util/RelayConcreteNode');
|
|
38
43
|
const {generateClientID, isClientID} = require('./ClientID');
|
|
44
|
+
const {getLocalVariables} = require('./RelayConcreteVariables');
|
|
39
45
|
const {createNormalizationSelector} = require('./RelayModernSelector');
|
|
40
46
|
const {
|
|
41
47
|
refineToReactFlightPayloadData,
|
|
@@ -55,8 +61,10 @@ const {
|
|
|
55
61
|
} = require('./RelayStoreUtils');
|
|
56
62
|
const {generateTypeID, TYPE_SCHEMA_TYPE} = require('./TypeID');
|
|
57
63
|
|
|
64
|
+
import type {ActorIdentifier} from '../multi-actor-environment/ActorIdentifier';
|
|
58
65
|
import type {PayloadData} from '../network/RelayNetworkTypes';
|
|
59
66
|
import type {
|
|
67
|
+
NormalizationActorChange,
|
|
60
68
|
NormalizationDefer,
|
|
61
69
|
NormalizationFlightField,
|
|
62
70
|
NormalizationLinkedField,
|
|
@@ -67,13 +75,13 @@ import type {
|
|
|
67
75
|
} from '../util/NormalizationNode';
|
|
68
76
|
import type {DataID, Variables} from '../util/RelayRuntimeTypes';
|
|
69
77
|
import type {
|
|
78
|
+
FollowupPayload,
|
|
70
79
|
HandleFieldPayload,
|
|
71
80
|
IncrementalDataPlaceholder,
|
|
72
|
-
ModuleImportPayload,
|
|
73
81
|
MutableRecordSource,
|
|
74
82
|
NormalizationSelector,
|
|
75
|
-
ReactFlightReachableExecutableDefinitions,
|
|
76
83
|
ReactFlightPayloadDeserializer,
|
|
84
|
+
ReactFlightReachableExecutableDefinitions,
|
|
77
85
|
ReactFlightServerErrorHandler,
|
|
78
86
|
Record,
|
|
79
87
|
RelayResponsePayload,
|
|
@@ -91,6 +99,7 @@ export type NormalizationOptions = {|
|
|
|
91
99
|
+reactFlightPayloadDeserializer?: ?ReactFlightPayloadDeserializer,
|
|
92
100
|
+reactFlightServerErrorHandler?: ?ReactFlightServerErrorHandler,
|
|
93
101
|
+shouldProcessClientComponents?: ?boolean,
|
|
102
|
+
+actorIdentifier?: ?ActorIdentifier,
|
|
94
103
|
|};
|
|
95
104
|
|
|
96
105
|
/**
|
|
@@ -118,13 +127,14 @@ function normalize(
|
|
|
118
127
|
* Helper for handling payloads.
|
|
119
128
|
*/
|
|
120
129
|
class RelayResponseNormalizer {
|
|
130
|
+
_actorIdentifier: ?ActorIdentifier;
|
|
121
131
|
_getDataId: GetDataID;
|
|
122
132
|
_handleFieldPayloads: Array<HandleFieldPayload>;
|
|
123
133
|
_treatMissingFieldsAsNull: boolean;
|
|
124
134
|
_incrementalPlaceholders: Array<IncrementalDataPlaceholder>;
|
|
125
135
|
_isClientExtension: boolean;
|
|
126
136
|
_isUnmatchedAbstractType: boolean;
|
|
127
|
-
|
|
137
|
+
_followupPayloads: Array<FollowupPayload>;
|
|
128
138
|
_path: Array<string>;
|
|
129
139
|
_recordSource: MutableRecordSource;
|
|
130
140
|
_variables: Variables;
|
|
@@ -137,13 +147,14 @@ class RelayResponseNormalizer {
|
|
|
137
147
|
variables: Variables,
|
|
138
148
|
options: NormalizationOptions,
|
|
139
149
|
) {
|
|
150
|
+
this._actorIdentifier = options.actorIdentifier;
|
|
140
151
|
this._getDataId = options.getDataID;
|
|
141
152
|
this._handleFieldPayloads = [];
|
|
142
153
|
this._treatMissingFieldsAsNull = options.treatMissingFieldsAsNull;
|
|
143
154
|
this._incrementalPlaceholders = [];
|
|
144
155
|
this._isClientExtension = false;
|
|
145
156
|
this._isUnmatchedAbstractType = false;
|
|
146
|
-
this.
|
|
157
|
+
this._followupPayloads = [];
|
|
147
158
|
this._path = options.path ? [...options.path] : [];
|
|
148
159
|
this._recordSource = recordSource;
|
|
149
160
|
this._variables = variables;
|
|
@@ -169,7 +180,7 @@ class RelayResponseNormalizer {
|
|
|
169
180
|
errors: null,
|
|
170
181
|
fieldPayloads: this._handleFieldPayloads,
|
|
171
182
|
incrementalPlaceholders: this._incrementalPlaceholders,
|
|
172
|
-
|
|
183
|
+
followupPayloads: this._followupPayloads,
|
|
173
184
|
source: this._recordSource,
|
|
174
185
|
isFinal: false,
|
|
175
186
|
};
|
|
@@ -208,13 +219,22 @@ class RelayResponseNormalizer {
|
|
|
208
219
|
this._normalizeField(node, selection, record, data);
|
|
209
220
|
break;
|
|
210
221
|
case CONDITION:
|
|
211
|
-
const conditionValue =
|
|
222
|
+
const conditionValue = Boolean(
|
|
223
|
+
this._getVariableValue(selection.condition),
|
|
224
|
+
);
|
|
212
225
|
if (conditionValue === selection.passingValue) {
|
|
213
226
|
this._traverseSelections(selection, record, data);
|
|
214
227
|
}
|
|
215
228
|
break;
|
|
216
229
|
case FRAGMENT_SPREAD: {
|
|
230
|
+
const prevVariables = this._variables;
|
|
231
|
+
this._variables = getLocalVariables(
|
|
232
|
+
this._variables,
|
|
233
|
+
selection.fragment.argumentDefinitions,
|
|
234
|
+
selection.args,
|
|
235
|
+
);
|
|
217
236
|
this._traverseSelections(selection.fragment, record, data);
|
|
237
|
+
this._variables = prevVariables;
|
|
218
238
|
break;
|
|
219
239
|
}
|
|
220
240
|
case INLINE_FRAGMENT: {
|
|
@@ -224,7 +244,7 @@ class RelayResponseNormalizer {
|
|
|
224
244
|
if (typeName === selection.type) {
|
|
225
245
|
this._traverseSelections(selection, record, data);
|
|
226
246
|
}
|
|
227
|
-
} else
|
|
247
|
+
} else {
|
|
228
248
|
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
229
249
|
const typeName = RelayModernRecord.getType(record);
|
|
230
250
|
const typeID = generateTypeID(typeName);
|
|
@@ -241,36 +261,24 @@ class RelayResponseNormalizer {
|
|
|
241
261
|
if (implementsInterface) {
|
|
242
262
|
this._traverseSelections(selection, record, data);
|
|
243
263
|
}
|
|
244
|
-
} else {
|
|
245
|
-
// legacy behavior for abstract refinements: always normalize even
|
|
246
|
-
// if the type doesn't conform, but track if the type matches or not
|
|
247
|
-
// for determining whether response fields are expected to be present
|
|
248
|
-
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
249
|
-
const parentIsUnmatchedAbstractType = this._isUnmatchedAbstractType;
|
|
250
|
-
this._isUnmatchedAbstractType =
|
|
251
|
-
this._isUnmatchedAbstractType || !implementsInterface;
|
|
252
|
-
this._traverseSelections(selection, record, data);
|
|
253
|
-
this._isUnmatchedAbstractType = parentIsUnmatchedAbstractType;
|
|
254
264
|
}
|
|
255
265
|
break;
|
|
256
266
|
}
|
|
257
267
|
case TYPE_DISCRIMINATOR: {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
this._recordSource.set(typeID, typeRecord);
|
|
267
|
-
}
|
|
268
|
-
RelayModernRecord.setValue(
|
|
269
|
-
typeRecord,
|
|
270
|
-
abstractKey,
|
|
271
|
-
implementsInterface,
|
|
272
|
-
);
|
|
268
|
+
const {abstractKey} = selection;
|
|
269
|
+
const implementsInterface = data.hasOwnProperty(abstractKey);
|
|
270
|
+
const typeName = RelayModernRecord.getType(record);
|
|
271
|
+
const typeID = generateTypeID(typeName);
|
|
272
|
+
let typeRecord = this._recordSource.get(typeID);
|
|
273
|
+
if (typeRecord == null) {
|
|
274
|
+
typeRecord = RelayModernRecord.create(typeID, TYPE_SCHEMA_TYPE);
|
|
275
|
+
this._recordSource.set(typeID, typeRecord);
|
|
273
276
|
}
|
|
277
|
+
RelayModernRecord.setValue(
|
|
278
|
+
typeRecord,
|
|
279
|
+
abstractKey,
|
|
280
|
+
implementsInterface,
|
|
281
|
+
);
|
|
274
282
|
break;
|
|
275
283
|
}
|
|
276
284
|
case LINKED_HANDLE:
|
|
@@ -281,13 +289,17 @@ class RelayResponseNormalizer {
|
|
|
281
289
|
const fieldKey = getStorageKey(selection, this._variables);
|
|
282
290
|
const handleKey = getHandleStorageKey(selection, this._variables);
|
|
283
291
|
this._handleFieldPayloads.push({
|
|
292
|
+
/* $FlowFixMe[class-object-subtyping] added when improving typing
|
|
293
|
+
* for this parameters */
|
|
284
294
|
args,
|
|
285
295
|
dataID: RelayModernRecord.getDataID(record),
|
|
286
296
|
fieldKey,
|
|
287
297
|
handle: selection.handle,
|
|
288
298
|
handleKey,
|
|
289
299
|
handleArgs: selection.handleArgs
|
|
290
|
-
?
|
|
300
|
+
? /* $FlowFixMe[class-object-subtyping] added when improving typing
|
|
301
|
+
* for this parameters */
|
|
302
|
+
getArgumentValues(selection.handleArgs, this._variables)
|
|
291
303
|
: {},
|
|
292
304
|
});
|
|
293
305
|
break;
|
|
@@ -319,6 +331,9 @@ class RelayResponseNormalizer {
|
|
|
319
331
|
throw new Error('Flight fields are not yet supported.');
|
|
320
332
|
}
|
|
321
333
|
break;
|
|
334
|
+
case ACTOR_CHANGE:
|
|
335
|
+
this._normalizeActorChange(node, selection, record, data);
|
|
336
|
+
break;
|
|
322
337
|
default:
|
|
323
338
|
(selection: empty);
|
|
324
339
|
invariant(
|
|
@@ -362,6 +377,7 @@ class RelayResponseNormalizer {
|
|
|
362
377
|
this._variables,
|
|
363
378
|
),
|
|
364
379
|
typeName: RelayModernRecord.getType(record),
|
|
380
|
+
actorIdentifier: this._actorIdentifier,
|
|
365
381
|
});
|
|
366
382
|
}
|
|
367
383
|
}
|
|
@@ -394,6 +410,7 @@ class RelayResponseNormalizer {
|
|
|
394
410
|
parentID: RelayModernRecord.getDataID(record),
|
|
395
411
|
node: stream,
|
|
396
412
|
variables: this._variables,
|
|
413
|
+
actorIdentifier: this._actorIdentifier,
|
|
397
414
|
});
|
|
398
415
|
}
|
|
399
416
|
}
|
|
@@ -424,13 +441,16 @@ class RelayResponseNormalizer {
|
|
|
424
441
|
operationReference ?? null,
|
|
425
442
|
);
|
|
426
443
|
if (operationReference != null) {
|
|
427
|
-
this.
|
|
444
|
+
this._followupPayloads.push({
|
|
445
|
+
kind: 'ModuleImportPayload',
|
|
446
|
+
args: moduleImport.args,
|
|
428
447
|
data,
|
|
429
448
|
dataID: RelayModernRecord.getDataID(record),
|
|
430
449
|
operationReference,
|
|
431
450
|
path: [...this._path],
|
|
432
451
|
typeName,
|
|
433
452
|
variables: this._variables,
|
|
453
|
+
actorIdentifier: this._actorIdentifier,
|
|
434
454
|
});
|
|
435
455
|
}
|
|
436
456
|
}
|
|
@@ -523,6 +543,99 @@ class RelayResponseNormalizer {
|
|
|
523
543
|
}
|
|
524
544
|
}
|
|
525
545
|
|
|
546
|
+
_normalizeActorChange(
|
|
547
|
+
parent: NormalizationNode,
|
|
548
|
+
selection: NormalizationActorChange,
|
|
549
|
+
record: Record,
|
|
550
|
+
data: PayloadData,
|
|
551
|
+
) {
|
|
552
|
+
const field = selection.linkedField;
|
|
553
|
+
invariant(
|
|
554
|
+
typeof data === 'object' && data,
|
|
555
|
+
'_normalizeActorChange(): Expected data for field `%s` to be an object.',
|
|
556
|
+
field.name,
|
|
557
|
+
);
|
|
558
|
+
const responseKey = field.alias || field.name;
|
|
559
|
+
const storageKey = getStorageKey(field, this._variables);
|
|
560
|
+
const fieldValue = data[responseKey];
|
|
561
|
+
|
|
562
|
+
if (fieldValue == null) {
|
|
563
|
+
if (fieldValue === undefined) {
|
|
564
|
+
const isOptionalField =
|
|
565
|
+
this._isClientExtension || this._isUnmatchedAbstractType;
|
|
566
|
+
|
|
567
|
+
if (isOptionalField) {
|
|
568
|
+
return;
|
|
569
|
+
} else if (!this._treatMissingFieldsAsNull) {
|
|
570
|
+
if (__DEV__) {
|
|
571
|
+
warning(
|
|
572
|
+
false,
|
|
573
|
+
'RelayResponseNormalizer: Payload did not contain a value ' +
|
|
574
|
+
'for field `%s: %s`. Check that you are parsing with the same ' +
|
|
575
|
+
'query that was used to fetch the payload.',
|
|
576
|
+
responseKey,
|
|
577
|
+
storageKey,
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const actorIdentifier = getActorIdentifierFromPayload(fieldValue);
|
|
588
|
+
if (actorIdentifier == null) {
|
|
589
|
+
if (__DEV__) {
|
|
590
|
+
warning(
|
|
591
|
+
false,
|
|
592
|
+
'RelayResponseNormalizer: Payload did not contain a value ' +
|
|
593
|
+
'for field `%s`. Check that you are parsing with the same ' +
|
|
594
|
+
'query that was used to fetch the payload. Payload is `%s`.',
|
|
595
|
+
ACTOR_IDENTIFIER_FIELD_NAME,
|
|
596
|
+
JSON.stringify(fieldValue, null, 2),
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
RelayModernRecord.setValue(record, storageKey, null);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// $FlowFixMe[incompatible-call]
|
|
604
|
+
const typeName = field.concreteType ?? this._getRecordType(fieldValue);
|
|
605
|
+
const nextID =
|
|
606
|
+
this._getDataId(
|
|
607
|
+
// $FlowFixMe[incompatible-call]
|
|
608
|
+
fieldValue,
|
|
609
|
+
typeName,
|
|
610
|
+
) ||
|
|
611
|
+
RelayModernRecord.getLinkedRecordID(record, storageKey) ||
|
|
612
|
+
generateClientID(RelayModernRecord.getDataID(record), storageKey);
|
|
613
|
+
|
|
614
|
+
invariant(
|
|
615
|
+
typeof nextID === 'string',
|
|
616
|
+
'RelayResponseNormalizer: Expected id on field `%s` to be a string.',
|
|
617
|
+
storageKey,
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
RelayModernRecord.setActorLinkedRecordID(
|
|
621
|
+
record,
|
|
622
|
+
storageKey,
|
|
623
|
+
actorIdentifier,
|
|
624
|
+
nextID,
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
this._followupPayloads.push({
|
|
628
|
+
kind: 'ActorPayload',
|
|
629
|
+
data: (fieldValue: $FlowFixMe),
|
|
630
|
+
dataID: nextID,
|
|
631
|
+
path: [...this._path, responseKey],
|
|
632
|
+
typeName,
|
|
633
|
+
variables: this._variables,
|
|
634
|
+
node: field,
|
|
635
|
+
actorIdentifier,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
526
639
|
_normalizeFlightField(
|
|
527
640
|
parent: NormalizationNode,
|
|
528
641
|
selection: NormalizationFlightField,
|
|
@@ -546,20 +659,17 @@ class RelayResponseNormalizer {
|
|
|
546
659
|
// Field not expected to exist regardless of whether the server is pruning null
|
|
547
660
|
// fields or not.
|
|
548
661
|
return;
|
|
549
|
-
} else
|
|
662
|
+
} else {
|
|
550
663
|
// Not optional and the server is not pruning null fields: field is expected
|
|
551
664
|
// to be present
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
'
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
);
|
|
561
|
-
}
|
|
562
|
-
return;
|
|
665
|
+
invariant(
|
|
666
|
+
this._treatMissingFieldsAsNull,
|
|
667
|
+
'RelayResponseNormalizer: Payload did not contain a value for ' +
|
|
668
|
+
'field `%s: %s`. Check that you are parsing with the same ' +
|
|
669
|
+
'query that was used to fetch the payload.',
|
|
670
|
+
responseKey,
|
|
671
|
+
storageKey,
|
|
672
|
+
);
|
|
563
673
|
}
|
|
564
674
|
}
|
|
565
675
|
RelayModernRecord.setValue(record, storageKey, null);
|
|
@@ -658,13 +768,16 @@ class RelayResponseNormalizer {
|
|
|
658
768
|
const reachableExecutableDefinitions: Array<ReactFlightReachableExecutableDefinitions> = [];
|
|
659
769
|
for (const query of reactFlightPayload.queries) {
|
|
660
770
|
if (query.response.data != null) {
|
|
661
|
-
this.
|
|
771
|
+
this._followupPayloads.push({
|
|
772
|
+
kind: 'ModuleImportPayload',
|
|
773
|
+
args: null,
|
|
662
774
|
data: query.response.data,
|
|
663
775
|
dataID: ROOT_ID,
|
|
664
776
|
operationReference: query.module,
|
|
665
777
|
path: [],
|
|
666
778
|
typeName: ROOT_TYPE,
|
|
667
779
|
variables: query.variables,
|
|
780
|
+
actorIdentifier: this._actorIdentifier,
|
|
668
781
|
});
|
|
669
782
|
}
|
|
670
783
|
reachableExecutableDefinitions.push({
|
|
@@ -674,13 +787,16 @@ class RelayResponseNormalizer {
|
|
|
674
787
|
}
|
|
675
788
|
for (const fragment of reactFlightPayload.fragments) {
|
|
676
789
|
if (fragment.response.data != null) {
|
|
677
|
-
this.
|
|
790
|
+
this._followupPayloads.push({
|
|
791
|
+
kind: 'ModuleImportPayload',
|
|
792
|
+
args: null,
|
|
678
793
|
data: fragment.response.data,
|
|
679
794
|
dataID: fragment.__id,
|
|
680
795
|
operationReference: fragment.module,
|
|
681
796
|
path: [],
|
|
682
797
|
typeName: fragment.__typename,
|
|
683
798
|
variables: fragment.variables,
|
|
799
|
+
actorIdentifier: this._actorIdentifier,
|
|
684
800
|
});
|
|
685
801
|
}
|
|
686
802
|
reachableExecutableDefinitions.push({
|
|
@@ -51,13 +51,7 @@ function getReactFlightClientResponse(
|
|
|
51
51
|
'got %s.',
|
|
52
52
|
record,
|
|
53
53
|
);
|
|
54
|
-
|
|
55
|
-
REACT_FLIGHT_TREE_STORAGE_KEY
|
|
56
|
-
]: $FlowFixMe);
|
|
57
|
-
if (response != null) {
|
|
58
|
-
return response;
|
|
59
|
-
}
|
|
60
|
-
return null;
|
|
54
|
+
return (record[REACT_FLIGHT_TREE_STORAGE_KEY]: $FlowFixMe);
|
|
61
55
|
}
|
|
62
56
|
|
|
63
57
|
module.exports = {
|
|
@@ -29,6 +29,7 @@ import type {
|
|
|
29
29
|
Snapshot,
|
|
30
30
|
StoreSubscriptions,
|
|
31
31
|
} from './RelayStoreTypes';
|
|
32
|
+
import type {ResolverCache} from './ResolverCache';
|
|
32
33
|
|
|
33
34
|
type Subscription = {|
|
|
34
35
|
callback: (snapshot: Snapshot) => void,
|
|
@@ -40,10 +41,12 @@ type Subscription = {|
|
|
|
40
41
|
class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
41
42
|
_subscriptions: Set<Subscription>;
|
|
42
43
|
__log: ?LogFunction;
|
|
44
|
+
_resolverCache: ResolverCache;
|
|
43
45
|
|
|
44
|
-
constructor(log?: ?LogFunction) {
|
|
46
|
+
constructor(log?: ?LogFunction, resolverCache: ResolverCache) {
|
|
45
47
|
this._subscriptions = new Set();
|
|
46
48
|
this.__log = log;
|
|
49
|
+
this._resolverCache = resolverCache;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
subscribe(
|
|
@@ -77,7 +80,11 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
77
80
|
return;
|
|
78
81
|
}
|
|
79
82
|
const snapshot = subscription.snapshot;
|
|
80
|
-
const backup = RelayReader.read(
|
|
83
|
+
const backup = RelayReader.read(
|
|
84
|
+
source,
|
|
85
|
+
snapshot.selector,
|
|
86
|
+
this._resolverCache,
|
|
87
|
+
);
|
|
81
88
|
const nextData = recycleNodesInto(snapshot.data, backup.data);
|
|
82
89
|
(backup: $FlowFixMe).data = nextData; // backup owns the snapshot and can safely mutate
|
|
83
90
|
subscription.backup = backup;
|
|
@@ -150,7 +157,7 @@ class RelayStoreSubscriptions implements StoreSubscriptions {
|
|
|
150
157
|
}
|
|
151
158
|
let nextSnapshot: Snapshot =
|
|
152
159
|
hasOverlappingUpdates || !backup
|
|
153
|
-
? RelayReader.read(source, snapshot.selector)
|
|
160
|
+
? RelayReader.read(source, snapshot.selector, this._resolverCache)
|
|
154
161
|
: backup;
|
|
155
162
|
const nextData = recycleNodesInto(snapshot.data, nextSnapshot.data);
|
|
156
163
|
nextSnapshot = ({
|