@@ -3,16 +3,12 @@ import { isSameSet } from '../jsutils/isSameSet.js';
3
3
4
4
import type { DeferUsage , FieldDetails } from './collectFields.js' ;
5
5
6
- export const NON_DEFERRED_TARGET_SET : TargetSet = new Set < Target > ( [ undefined ] ) ;
7
-
8
- export type Target = DeferUsage | undefined ;
9
- export type TargetSet = ReadonlySet < Target > ;
10
6
export type DeferUsageSet = ReadonlySet < DeferUsage > ;
11
7
12
8
export interface FieldGroup {
13
9
fields : ReadonlyArray < FieldDetails > ;
14
- targets ?: TargetSet | undefined ;
15
- knownTargets ?: TargetSet | undefined ;
10
+ deferUsages ?: DeferUsageSet | undefined ;
11
+ knownDeferUsages ?: DeferUsageSet | undefined ;
16
12
}
17
13
18
14
export type GroupedFieldSet = Map < string , FieldGroup > ;
@@ -24,19 +20,23 @@ export interface NewGroupedFieldSetDetails {
24
20
25
21
export function buildFieldPlan (
26
22
fields : Map < string , ReadonlyArray < FieldDetails > > ,
27
- parentTargets = NON_DEFERRED_TARGET_SET ,
28
- knownTargets = NON_DEFERRED_TARGET_SET ,
23
+ parentDeferUsages : DeferUsageSet = new Set < DeferUsage > ( ) ,
24
+ knownDeferUsages : DeferUsageSet = new Set < DeferUsage > ( ) ,
29
25
) : {
30
26
groupedFieldSet : GroupedFieldSet ;
31
27
newGroupedFieldSetDetailsMap : Map < DeferUsageSet , NewGroupedFieldSetDetails > ;
32
28
newDeferUsages : ReadonlyArray < DeferUsage > ;
33
29
} {
34
30
const newDeferUsages : Set < DeferUsage > = new Set < DeferUsage > ( ) ;
35
- const newKnownTargets = new Set < Target > ( knownTargets ) ;
31
+ const newKnownDeferUsages = new Set < DeferUsage > ( knownDeferUsages ) ;
36
32
37
33
const groupedFieldSet = new Map <
38
34
string ,
39
- { fields : Array < FieldDetails > ; targets : TargetSet ; knownTargets : TargetSet }
35
+ {
36
+ fields : Array < FieldDetails > ;
37
+ deferUsages : DeferUsageSet ;
38
+ knownDeferUsages : DeferUsageSet ;
39
+ }
40
40
> ( ) ;
41
41
42
42
const newGroupedFieldSetDetailsMap = new Map <
@@ -46,8 +46,8 @@ export function buildFieldPlan(
46
46
string ,
47
47
{
48
48
fields : Array < FieldDetails > ;
49
- targets : TargetSet ;
50
- knownTargets : TargetSet ;
49
+ deferUsages : DeferUsageSet ;
50
+ knownDeferUsages : DeferUsageSet ;
51
51
}
52
52
> ;
53
53
shouldInitiateDefer : boolean ;
@@ -56,41 +56,50 @@ export function buildFieldPlan(
56
56
57
57
const map = new Map <
58
58
string ,
59
- { targetSet : TargetSet ; fieldDetailsList : ReadonlyArray < FieldDetails > }
59
+ {
60
+ deferUsageSet : DeferUsageSet ;
61
+ fieldDetailsList : ReadonlyArray < FieldDetails > ;
62
+ }
60
63
> ( ) ;
64
+
61
65
for ( const [ responseKey , fieldDetailsList ] of fields ) {
62
- const targetSet = new Set < Target > ( ) ;
66
+ const deferUsageSet = new Set < DeferUsage > ( ) ;
67
+ let inOriginalResult = false ;
63
68
for ( const fieldDetails of fieldDetailsList ) {
64
- const target = fieldDetails . deferUsage ;
65
- targetSet . add ( target ) ;
66
- if ( ! knownTargets . has ( target ) ) {
67
- // all targets that are not known must be defined
68
- newDeferUsages . add ( target as DeferUsage ) ;
69
+ const deferUsage = fieldDetails . deferUsage ;
70
+ if ( deferUsage === undefined ) {
71
+ inOriginalResult = true ;
72
+ continue ;
69
73
}
70
- newKnownTargets . add ( target ) ;
71
- }
72
- map . set ( responseKey , { targetSet, fieldDetailsList } ) ;
73
- }
74
-
75
- for ( const [ responseKey , { targetSet, fieldDetailsList } ] of map ) {
76
- const maskingTargetList : Array < Target > = [ ] ;
77
- for ( const target of targetSet ) {
78
- if (
79
- target === undefined ||
80
- getAncestors ( target ) . every ( ( ancestor ) => ! targetSet . has ( ancestor ) )
81
- ) {
82
- maskingTargetList . push ( target ) ;
74
+ deferUsageSet . add ( deferUsage ) ;
75
+ if ( ! knownDeferUsages . has ( deferUsage ) ) {
76
+ newDeferUsages . add ( deferUsage ) ;
77
+ newKnownDeferUsages . add ( deferUsage ) ;
83
78
}
84
79
}
80
+ if ( inOriginalResult ) {
81
+ deferUsageSet . clear ( ) ;
82
+ } else {
83
+ deferUsageSet . forEach ( ( deferUsage ) => {
84
+ const ancestors = getAncestors ( deferUsage ) ;
85
+ for ( const ancestor of ancestors ) {
86
+ if ( deferUsageSet . has ( ancestor ) ) {
87
+ deferUsageSet . delete ( deferUsage ) ;
88
+ }
89
+ }
90
+ } ) ;
91
+ }
92
+ map . set ( responseKey , { deferUsageSet, fieldDetailsList } ) ;
93
+ }
85
94
86
- const maskingTargets : TargetSet = new Set < Target > ( maskingTargetList ) ;
87
- if ( isSameSet ( maskingTargets , parentTargets ) ) {
95
+ for ( const [ responseKey , { deferUsageSet , fieldDetailsList } ] of map ) {
96
+ if ( isSameSet ( deferUsageSet , parentDeferUsages ) ) {
88
97
let fieldGroup = groupedFieldSet . get ( responseKey ) ;
89
98
if ( fieldGroup === undefined ) {
90
99
fieldGroup = {
91
100
fields : [ ] ,
92
- targets : maskingTargets ,
93
- knownTargets : newKnownTargets ,
101
+ deferUsages : deferUsageSet ,
102
+ knownDeferUsages : newKnownDeferUsages ,
94
103
} ;
95
104
groupedFieldSet . set ( responseKey , fieldGroup ) ;
96
105
}
@@ -100,28 +109,27 @@ export function buildFieldPlan(
100
109
101
110
let newGroupedFieldSetDetails = getBySet (
102
111
newGroupedFieldSetDetailsMap ,
103
- maskingTargets ,
112
+ deferUsageSet ,
104
113
) ;
105
114
let newGroupedFieldSet ;
106
115
if ( newGroupedFieldSetDetails === undefined ) {
107
116
newGroupedFieldSet = new Map <
108
117
string ,
109
118
{
110
119
fields : Array < FieldDetails > ;
111
- targets : TargetSet ;
112
- knownTargets : TargetSet ;
120
+ deferUsages : DeferUsageSet ;
121
+ knownDeferUsages : DeferUsageSet ;
113
122
}
114
123
> ( ) ;
115
124
116
125
newGroupedFieldSetDetails = {
117
126
groupedFieldSet : newGroupedFieldSet ,
118
- shouldInitiateDefer : maskingTargetList . some (
119
- ( deferUsage ) => ! parentTargets . has ( deferUsage ) ,
127
+ shouldInitiateDefer : Array . from ( deferUsageSet ) . some (
128
+ ( deferUsage ) => ! parentDeferUsages . has ( deferUsage ) ,
120
129
) ,
121
130
} ;
122
131
newGroupedFieldSetDetailsMap . set (
123
- // all new grouped field sets must not contain the initial result as a target
124
- maskingTargets as DeferUsageSet ,
132
+ deferUsageSet ,
125
133
newGroupedFieldSetDetails ,
126
134
) ;
127
135
} else {
@@ -131,8 +139,8 @@ export function buildFieldPlan(
131
139
if ( fieldGroup === undefined ) {
132
140
fieldGroup = {
133
141
fields : [ ] ,
134
- targets : maskingTargets ,
135
- knownTargets : newKnownTargets ,
142
+ deferUsages : deferUsageSet ,
143
+ knownDeferUsages : newKnownDeferUsages ,
136
144
} ;
137
145
newGroupedFieldSet . set ( responseKey , fieldGroup ) ;
138
146
}
@@ -146,14 +154,12 @@ export function buildFieldPlan(
146
154
} ;
147
155
}
148
156
149
- function getAncestors (
150
- deferUsage : DeferUsage ,
151
- ) : ReadonlyArray < DeferUsage | undefined > {
157
+ function getAncestors ( deferUsage : DeferUsage ) : ReadonlyArray < DeferUsage > {
158
+ const ancestors : Array < DeferUsage > = [ ] ;
152
159
let parentDeferUsage : DeferUsage | undefined = deferUsage . parentDeferUsage ;
153
- const ancestors : Array < DeferUsage | undefined > = [ parentDeferUsage ] ;
154
160
while ( parentDeferUsage !== undefined ) {
155
- parentDeferUsage = parentDeferUsage . parentDeferUsage ;
156
161
ancestors . unshift ( parentDeferUsage ) ;
162
+ parentDeferUsage = parentDeferUsage . parentDeferUsage ;
157
163
}
158
164
return ancestors ;
159
165
}
0 commit comments