@@ -275,10 +275,37 @@ extension GraphQLScalarType: Hashable {
275275public final class GraphQLObjectType : @unchecked Sendable {
276276 public let name : String
277277 public let description : String ?
278+
278279 // While technically not sendable, fields and interfaces should not be mutated after schema
279280 // creation.
280- public var fields : ( ) throws -> GraphQLFieldMap
281- public var interfaces : ( ) throws -> [ GraphQLInterfaceType ]
281+ public var fields : ( ) throws -> GraphQLFieldMap {
282+ get {
283+ fieldFunc
284+ }
285+ set {
286+ fieldFunc = newValue
287+ // Clear the cache when setting a new function
288+ fieldCache = nil
289+ }
290+ }
291+
292+ private var fieldFunc : ( ) throws -> GraphQLFieldMap
293+ private var fieldCache : GraphQLFieldDefinitionMap ?
294+
295+ public var interfaces : ( ) throws -> [ GraphQLInterfaceType ] {
296+ get {
297+ interfaceFunc
298+ }
299+ set {
300+ interfaceFunc = newValue
301+ // Clear the cache when setting a new function
302+ interfaceCache = nil
303+ }
304+ }
305+
306+ private var interfaceFunc : ( ) throws -> [ GraphQLInterfaceType ]
307+ private var interfaceCache : [ GraphQLInterfaceType ] ?
308+
282309 public let isTypeOf : GraphQLIsTypeOf ?
283310 public let astNode : ObjectTypeDefinition ?
284311 public let extensionASTNodes : [ TypeExtensionDefinition ]
@@ -296,8 +323,8 @@ public final class GraphQLObjectType: @unchecked Sendable {
296323 try assertValid ( name: name)
297324 self . name = name
298325 self . description = description
299- self . fields = { fields }
300- self . interfaces = { interfaces }
326+ fieldFunc = { fields }
327+ interfaceFunc = { interfaces }
301328 self . isTypeOf = isTypeOf
302329 self . astNode = astNode
303330 self . extensionASTNodes = extensionASTNodes
@@ -315,22 +342,32 @@ public final class GraphQLObjectType: @unchecked Sendable {
315342 try assertValid ( name: name)
316343 self . name = name
317344 self . description = description
318- self . fields = fields
319- self . interfaces = interfaces
345+ fieldFunc = fields
346+ interfaceFunc = interfaces
320347 self . isTypeOf = isTypeOf
321348 self . astNode = astNode
322349 self . extensionASTNodes = extensionASTNodes
323350 }
324351
325352 func getFields( ) throws -> GraphQLFieldDefinitionMap {
326- try defineFieldMap (
327- name: name,
328- fields: fields ( )
329- )
353+ // Cache on the first call
354+ return try fieldCache ?? {
355+ let fields = try defineFieldMap (
356+ name: name,
357+ fields: fields ( )
358+ )
359+ self . fieldCache = fields
360+ return fields
361+ } ( )
330362 }
331363
332364 func getInterfaces( ) throws -> [ GraphQLInterfaceType ] {
333- return try interfaces ( )
365+ // Cache on the first call
366+ return try interfaceCache ?? {
367+ let interfaces = try interfaces ( )
368+ self . interfaceCache = interfaces
369+ return interfaces
370+ } ( )
334371 }
335372}
336373
@@ -657,10 +694,37 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
657694 public let name : String
658695 public let description : String ?
659696 public let resolveType : GraphQLTypeResolve ?
697+
660698 // While technically not sendable, fields and interfaces should not be mutated after schema
661699 // creation.
662- public var fields : ( ) throws -> GraphQLFieldMap
663- public var interfaces : ( ) throws -> [ GraphQLInterfaceType ]
700+ public var fields : ( ) throws -> GraphQLFieldMap {
701+ get {
702+ fieldFunc
703+ }
704+ set {
705+ fieldFunc = newValue
706+ // Clear the cache when setting a new function
707+ fieldCache = nil
708+ }
709+ }
710+
711+ private var fieldFunc : ( ) throws -> GraphQLFieldMap
712+ private var fieldCache : GraphQLFieldDefinitionMap ?
713+
714+ public var interfaces : ( ) throws -> [ GraphQLInterfaceType ] {
715+ get {
716+ interfaceFunc
717+ }
718+ set {
719+ interfaceFunc = newValue
720+ // Clear the cache when setting a new function
721+ interfaceCache = nil
722+ }
723+ }
724+
725+ private var interfaceFunc : ( ) throws -> [ GraphQLInterfaceType ]
726+ private var interfaceCache : [ GraphQLInterfaceType ] ?
727+
664728 public let astNode : InterfaceTypeDefinition ?
665729 public let extensionASTNodes : [ InterfaceExtensionDefinition ]
666730 public let kind : TypeKind = . interface
@@ -677,8 +741,8 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
677741 try assertValid ( name: name)
678742 self . name = name
679743 self . description = description
680- self . fields = { fields }
681- self . interfaces = { interfaces }
744+ fieldFunc = { fields }
745+ interfaceFunc = { interfaces }
682746 self . resolveType = resolveType
683747 self . astNode = astNode
684748 self . extensionASTNodes = extensionASTNodes
@@ -696,22 +760,32 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
696760 try assertValid ( name: name)
697761 self . name = name
698762 self . description = description
699- self . fields = fields
700- self . interfaces = interfaces
763+ fieldFunc = fields
764+ interfaceFunc = interfaces
701765 self . resolveType = resolveType
702766 self . astNode = astNode
703767 self . extensionASTNodes = extensionASTNodes
704768 }
705769
706770 func getFields( ) throws -> GraphQLFieldDefinitionMap {
707- try defineFieldMap (
708- name: name,
709- fields: fields ( )
710- )
771+ // Cache on the first call
772+ return try fieldCache ?? {
773+ let fields = try defineFieldMap (
774+ name: name,
775+ fields: fields ( )
776+ )
777+ self . fieldCache = fields
778+ return fields
779+ } ( )
711780 }
712781
713782 func getInterfaces( ) throws -> [ GraphQLInterfaceType ] {
714- return try interfaces ( )
783+ // Cache on the first call
784+ return try interfaceCache ?? {
785+ let interfaces = try interfaces ( )
786+ self . interfaceCache = interfaces
787+ return interfaces
788+ } ( )
715789 }
716790}
717791
0 commit comments