@@ -44,7 +44,7 @@ struct DeferredFragmentsMetadataTemplate {
4444 ) -> TemplateString {
4545 """
4646 enum DeferredFragmentIdentifiers {
47- \( deferredFragmentPathTypeInfo. map {
47+ \( deferredFragmentPathTypeInfo. unique ( by : { $0 . pathDeferConditionHash } ) . map {
4848 return """
4949 static let \( $0. deferCondition. label) = DeferredFragmentIdentifier(label: \" \( $0. deferCondition. label) \" , fieldPath: [ \
5050 \( $0. path. map { " \" \( $0) \" " } , separator: " , " ) \
@@ -75,6 +75,22 @@ struct DeferredFragmentsMetadataTemplate {
7575 let path : [ String ]
7676 let deferCondition : CompilationResult . DeferCondition
7777 let typeName : String
78+
79+ /// Provides a hash value that is a combination of `path` and `deferCondition` values only, `typeName` is not
80+ /// included.
81+ ///
82+ /// This is intended to be used when the selection set type does not matter, such as when generating a deferred
83+ /// fragment identifier which is shared amongst all child selection set types within a deferred fragment.
84+ ///
85+ /// - Returns: Hash value of `path` and `deferCondition`.
86+ var pathDeferConditionHash : Int {
87+ var hasher = Hasher ( )
88+
89+ hasher. combine ( path)
90+ hasher. combine ( deferCondition)
91+
92+ return hasher. finalize ( )
93+ }
7894 }
7995
8096 fileprivate func DeferredFragmentsPathTypeInfo(
@@ -134,3 +150,10 @@ struct DeferredFragmentsMetadataTemplate {
134150 return deferredPathTypeInfo
135151 }
136152}
153+
154+ fileprivate extension Sequence where Element == DeferredFragmentsMetadataTemplate . DeferredPathTypeInfo {
155+ func unique< T: Hashable > ( by keyForValue: ( Iterator . Element ) throws -> T ) rethrows -> [ Iterator . Element ] {
156+ var seen : Set < T > = [ ]
157+ return try filter { try seen. insert ( keyForValue ( $0) ) . inserted }
158+ }
159+ }
0 commit comments