File tree Expand file tree Collapse file tree 4 files changed +57
-10
lines changed Expand file tree Collapse file tree 4 files changed +57
-10
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ ' @urql/exchange-graphcache ' : minor
3
+ ---
4
+
5
+ Add possibleTypes config for deterministic fragment matching
Original file line number Diff line number Diff line change @@ -234,18 +234,24 @@ export class SelectionIterator {
234
234
fragment ,
235
235
this . typename
236
236
)
237
- : ( currentOperation === 'read' &&
238
- isFragmentMatching (
237
+ : this . ctx . store . possibleTypeMap
238
+ ? isSuperType (
239
+ this . ctx . store . possibleTypeMap ,
239
240
fragment . typeCondition . name . value ,
240
241
this . typename
241
- ) ) ||
242
- isFragmentHeuristicallyMatching (
243
- fragment ,
244
- this . typename ,
245
- this . entityKey ,
246
- this . ctx . variables ,
247
- this . ctx . store . logger
248
- ) ) ;
242
+ )
243
+ : ( currentOperation === 'read' &&
244
+ isFragmentMatching (
245
+ fragment . typeCondition . name . value ,
246
+ this . typename
247
+ ) ) ||
248
+ isFragmentHeuristicallyMatching (
249
+ fragment ,
250
+ this . typename ,
251
+ this . entityKey ,
252
+ this . ctx . variables ,
253
+ this . ctx . store . logger
254
+ ) ) ;
249
255
if (
250
256
isMatching ||
251
257
( currentOperation === 'write' && ! this . ctx . store . schema )
@@ -290,6 +296,19 @@ export class SelectionIterator {
290
296
}
291
297
}
292
298
299
+ const isSuperType = (
300
+ possibleTypeMap : Map < string , Set < string > > ,
301
+ typeCondition : string ,
302
+ typename : string | void
303
+ ) => {
304
+ if ( ! typename ) return false ;
305
+ if ( typeCondition === typename ) return true ;
306
+
307
+ const concreteTypes = possibleTypeMap . get ( typeCondition ) ;
308
+
309
+ return concreteTypes && concreteTypes . has ( typename ) ;
310
+ } ;
311
+
293
312
const isFragmentMatching = ( typeCondition : string , typename : string | void ) => {
294
313
if ( ! typename ) return false ;
295
314
if ( typeCondition === typename ) return true ;
Original file line number Diff line number Diff line change @@ -57,6 +57,7 @@ export class Store<
57
57
keys : KeyingConfig ;
58
58
globalIDs : Set < string > | boolean ;
59
59
schema ?: SchemaIntrospector ;
60
+ possibleTypeMap ?: Map < string , Set < string > > ;
60
61
61
62
rootFields : { query : string ; mutation : string ; subscription : string } ;
62
63
rootNames : { [ name : string ] : RootField | void } ;
@@ -86,6 +87,14 @@ export class Store<
86
87
if ( schema . types ) this . schema = schema ;
87
88
}
88
89
90
+ if ( ! this . schema && opts . possibleTypes ) {
91
+ this . possibleTypeMap = new Map ( ) ;
92
+ for ( const entry of Object . entries ( opts . possibleTypes ) ) {
93
+ const [ abstractType , concreteTypes ] = entry ;
94
+ this . possibleTypeMap . set ( abstractType , new Set ( concreteTypes ) ) ;
95
+ }
96
+ }
97
+
89
98
this . updates = opts . updates || { } ;
90
99
91
100
this . rootFields = {
Original file line number Diff line number Diff line change @@ -618,6 +618,16 @@ export type CacheExchangeOpts = {
618
618
* type names may be passed instead.
619
619
*/
620
620
globalIDs ?: string [ ] | boolean ;
621
+ /** Configures abstract to concrete types mapping for GraphQL types.
622
+ *
623
+ * @remarks
624
+ * This will disable heuristic fragment matching, allowing Graphcache to match
625
+ * fragment deterministically.
626
+ *
627
+ * When both `possibleTypes` and `schema` is set, `possibleTypes` value will be
628
+ * ignored.
629
+ */
630
+ possibleTypes ?: PossibleTypesConfig ;
621
631
/** Configures Graphcache with Schema Introspection data.
622
632
*
623
633
* @remarks
@@ -932,6 +942,10 @@ export type KeyingConfig = {
932
942
[ typename : string ] : KeyGenerator ;
933
943
} ;
934
944
945
+ export type PossibleTypesConfig = {
946
+ [ abstractType : string ] : string [ ] ;
947
+ } ;
948
+
935
949
/** Serialized normalized caching data. */
936
950
export interface SerializedEntries {
937
951
[ key : string ] : string | undefined ;
You can’t perform that action at this time.
0 commit comments