@@ -16,6 +16,7 @@ import type {PayloadData, PayloadError} from '../network/RelayNetworkTypes';
1616import type {
1717 NormalizationActorChange ,
1818 NormalizationDefer ,
19+ NormalizationInlineFragment ,
1920 NormalizationLinkedField ,
2021 NormalizationLiveResolverField ,
2122 NormalizationModuleImport ,
@@ -54,6 +55,7 @@ const RelayModernRecord = require('./RelayModernRecord');
5455const { createNormalizationSelector} = require ( './RelayModernSelector' ) ;
5556const {
5657 ROOT_ID ,
58+ ROOT_TYPE ,
5759 TYPENAME_KEY ,
5860 getArgumentValues,
5961 getHandleStorageKey,
@@ -243,34 +245,7 @@ class RelayResponseNormalizer {
243245 break ;
244246 }
245247 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 ) ;
274249 break ;
275250 }
276251 case 'TypeDiscriminator' : {
@@ -358,13 +333,62 @@ class RelayResponseNormalizer {
358333 }
359334 }
360335
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+
361379 _normalizeResolver (
362380 resolver : NormalizationResolverField | NormalizationLiveResolverField ,
363381 record : Record ,
364382 data : PayloadData ,
365383 ) {
366384 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+ }
368392 }
369393 }
370394
0 commit comments