@@ -16,6 +16,7 @@ import type {PayloadData, PayloadError} from '../network/RelayNetworkTypes';
16
16
import type {
17
17
NormalizationActorChange ,
18
18
NormalizationDefer ,
19
+ NormalizationInlineFragment ,
19
20
NormalizationLinkedField ,
20
21
NormalizationLiveResolverField ,
21
22
NormalizationModuleImport ,
@@ -54,6 +55,7 @@ const RelayModernRecord = require('./RelayModernRecord');
54
55
const { createNormalizationSelector} = require ( './RelayModernSelector' ) ;
55
56
const {
56
57
ROOT_ID ,
58
+ ROOT_TYPE ,
57
59
TYPENAME_KEY ,
58
60
getArgumentValues,
59
61
getHandleStorageKey,
@@ -243,34 +245,7 @@ class RelayResponseNormalizer {
243
245
break ;
244
246
}
245
247
case 'InlineFragment' : {
246
- const { abstractKey} = selection ;
247
- if ( abstractKey == null ) {
248
- const typeName = RelayModernRecord . getType ( record ) ;
249
- if ( typeName === selection . type ) {
250
- this . _traverseSelections ( selection , record , data ) ;
251
- }
252
- } else {
253
- // $FlowFixMe[method-unbinding] - data could be prototype less
254
- const implementsInterface = Object . prototype . hasOwnProperty . call (
255
- data ,
256
- abstractKey ,
257
- ) ;
258
- const typeName = RelayModernRecord . getType ( record ) ;
259
- const typeID = generateTypeID ( typeName ) ;
260
- let typeRecord = this . _recordSource . get ( typeID ) ;
261
- if ( typeRecord == null ) {
262
- typeRecord = RelayModernRecord . create ( typeID , TYPE_SCHEMA_TYPE ) ;
263
- this . _recordSource . set ( typeID , typeRecord ) ;
264
- }
265
- RelayModernRecord . setValue (
266
- typeRecord ,
267
- abstractKey ,
268
- implementsInterface ,
269
- ) ;
270
- if ( implementsInterface ) {
271
- this . _traverseSelections ( selection , record , data ) ;
272
- }
273
- }
248
+ this . _normalizeInlineFragment ( selection , record , data ) ;
274
249
break ;
275
250
}
276
251
case 'TypeDiscriminator' : {
@@ -358,13 +333,62 @@ class RelayResponseNormalizer {
358
333
}
359
334
}
360
335
336
+ _normalizeInlineFragment (
337
+ selection : NormalizationInlineFragment ,
338
+ record : Record ,
339
+ data : PayloadData ,
340
+ ) {
341
+ const { abstractKey} = selection ;
342
+ if ( abstractKey == null ) {
343
+ const typeName = RelayModernRecord . getType ( record ) ;
344
+ if (
345
+ typeName === selection . type ||
346
+ // The root record type is a special `__Root` type and may not match the
347
+ // type on the ast, so ignore type mismatches at the root. We currently
348
+ // detect whether we're at the root by checking against ROOT_ID, but this
349
+ // does not work for mutations/subscriptions which generate unique root
350
+ // ids. This is acceptable in practice as we don't read data for
351
+ // mutations/subscriptions in a situation where we would use
352
+ // isMissingData to decide whether to suspend or not.
353
+ // TODO T96653810: Correctly detect reading from root of mutation/subscription
354
+ ( typeName === ROOT_TYPE &&
355
+ ! RelayFeatureFlags . DISABLE_RESOLVER_ROOT_FRAGMENT_NORMALIZATION_BUG_FIX )
356
+ ) {
357
+ this . _traverseSelections ( selection , record , data ) ;
358
+ }
359
+ } else {
360
+ // $FlowFixMe[method-unbinding] - data could be prototype less
361
+ const implementsInterface = Object . prototype . hasOwnProperty . call (
362
+ data ,
363
+ abstractKey ,
364
+ ) ;
365
+ const typeName = RelayModernRecord . getType ( record ) ;
366
+ const typeID = generateTypeID ( typeName ) ;
367
+ let typeRecord = this . _recordSource . get ( typeID ) ;
368
+ if ( typeRecord == null ) {
369
+ typeRecord = RelayModernRecord . create ( typeID , TYPE_SCHEMA_TYPE ) ;
370
+ this . _recordSource . set ( typeID , typeRecord ) ;
371
+ }
372
+ RelayModernRecord . setValue ( typeRecord , abstractKey , implementsInterface ) ;
373
+ if ( implementsInterface ) {
374
+ this . _traverseSelections ( selection , record , data ) ;
375
+ }
376
+ }
377
+ }
378
+
361
379
_normalizeResolver (
362
380
resolver : NormalizationResolverField | NormalizationLiveResolverField ,
363
381
record : Record ,
364
382
data : PayloadData ,
365
383
) {
366
384
if ( resolver . fragment != null ) {
367
- this . _traverseSelections ( resolver . fragment , record , data ) ;
385
+ if (
386
+ RelayFeatureFlags . DISABLE_RESOLVER_ROOT_FRAGMENT_NORMALIZATION_BUG_FIX
387
+ ) {
388
+ this . _traverseSelections ( resolver . fragment , record , data ) ;
389
+ } else {
390
+ this . _normalizeInlineFragment ( resolver . fragment , record , data ) ;
391
+ }
368
392
}
369
393
}
370
394
0 commit comments