@@ -275,10 +275,35 @@ 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+ private var fieldFunc : ( ) throws -> GraphQLFieldMap
292+ private var fieldCache : GraphQLFieldDefinitionMap ? = nil
293+
294+ public var interfaces : ( ) throws -> [ GraphQLInterfaceType ] {
295+ get {
296+ interfaceFunc
297+ }
298+ set {
299+ interfaceFunc = newValue
300+ // Clear the cache when setting a new function
301+ interfaceCache = nil
302+ }
303+ }
304+ private var interfaceFunc : ( ) throws -> [ GraphQLInterfaceType ]
305+ private var interfaceCache : [ GraphQLInterfaceType ] ? = nil
306+
282307 public let isTypeOf : GraphQLIsTypeOf ?
283308 public let astNode : ObjectTypeDefinition ?
284309 public let extensionASTNodes : [ TypeExtensionDefinition ]
@@ -296,8 +321,8 @@ public final class GraphQLObjectType: @unchecked Sendable {
296321 try assertValid ( name: name)
297322 self . name = name
298323 self . description = description
299- self . fields = { fields }
300- self . interfaces = { interfaces }
324+ self . fieldFunc = { fields }
325+ self . interfaceFunc = { interfaces }
301326 self . isTypeOf = isTypeOf
302327 self . astNode = astNode
303328 self . extensionASTNodes = extensionASTNodes
@@ -315,22 +340,32 @@ public final class GraphQLObjectType: @unchecked Sendable {
315340 try assertValid ( name: name)
316341 self . name = name
317342 self . description = description
318- self . fields = fields
319- self . interfaces = interfaces
343+ self . fieldFunc = fields
344+ self . interfaceFunc = interfaces
320345 self . isTypeOf = isTypeOf
321346 self . astNode = astNode
322347 self . extensionASTNodes = extensionASTNodes
323348 }
324349
325350 func getFields( ) throws -> GraphQLFieldDefinitionMap {
326- try defineFieldMap (
327- name: name,
328- fields: fields ( )
329- )
351+ // Cache on the first call
352+ return try self . fieldCache ?? {
353+ let fields = try defineFieldMap (
354+ name: name,
355+ fields: fields ( )
356+ )
357+ self . fieldCache = fields
358+ return fields
359+ } ( )
330360 }
331361
332362 func getInterfaces( ) throws -> [ GraphQLInterfaceType ] {
333- return try interfaces ( )
363+ // Cache on the first call
364+ return try self . interfaceCache ?? {
365+ let interfaces = try interfaces ( )
366+ self . interfaceCache = interfaces
367+ return interfaces
368+ } ( )
334369 }
335370}
336371
@@ -657,10 +692,35 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
657692 public let name : String
658693 public let description : String ?
659694 public let resolveType : GraphQLTypeResolve ?
695+
660696 // While technically not sendable, fields and interfaces should not be mutated after schema
661697 // creation.
662- public var fields : ( ) throws -> GraphQLFieldMap
663- public var interfaces : ( ) throws -> [ GraphQLInterfaceType ]
698+ public var fields : ( ) throws -> GraphQLFieldMap {
699+ get {
700+ fieldFunc
701+ }
702+ set {
703+ fieldFunc = newValue
704+ // Clear the cache when setting a new function
705+ fieldCache = nil
706+ }
707+ }
708+ private var fieldFunc : ( ) throws -> GraphQLFieldMap
709+ private var fieldCache : GraphQLFieldDefinitionMap ? = nil
710+
711+ public var interfaces : ( ) throws -> [ GraphQLInterfaceType ] {
712+ get {
713+ interfaceFunc
714+ }
715+ set {
716+ interfaceFunc = newValue
717+ // Clear the cache when setting a new function
718+ interfaceCache = nil
719+ }
720+ }
721+ private var interfaceFunc : ( ) throws -> [ GraphQLInterfaceType ]
722+ private var interfaceCache : [ GraphQLInterfaceType ] ? = nil
723+
664724 public let astNode : InterfaceTypeDefinition ?
665725 public let extensionASTNodes : [ InterfaceExtensionDefinition ]
666726 public let kind : TypeKind = . interface
@@ -677,8 +737,8 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
677737 try assertValid ( name: name)
678738 self . name = name
679739 self . description = description
680- self . fields = { fields }
681- self . interfaces = { interfaces }
740+ self . fieldFunc = { fields }
741+ self . interfaceFunc = { interfaces }
682742 self . resolveType = resolveType
683743 self . astNode = astNode
684744 self . extensionASTNodes = extensionASTNodes
@@ -696,22 +756,32 @@ public final class GraphQLInterfaceType: @unchecked Sendable {
696756 try assertValid ( name: name)
697757 self . name = name
698758 self . description = description
699- self . fields = fields
700- self . interfaces = interfaces
759+ self . fieldFunc = fields
760+ self . interfaceFunc = interfaces
701761 self . resolveType = resolveType
702762 self . astNode = astNode
703763 self . extensionASTNodes = extensionASTNodes
704764 }
705765
706766 func getFields( ) throws -> GraphQLFieldDefinitionMap {
707- try defineFieldMap (
708- name: name,
709- fields: fields ( )
710- )
767+ // Cache on the first call
768+ return try self . fieldCache ?? {
769+ let fields = try defineFieldMap (
770+ name: name,
771+ fields: fields ( )
772+ )
773+ self . fieldCache = fields
774+ return fields
775+ } ( )
711776 }
712777
713778 func getInterfaces( ) throws -> [ GraphQLInterfaceType ] {
714- return try interfaces ( )
779+ // Cache on the first call
780+ return try self . interfaceCache ?? {
781+ let interfaces = try interfaces ( )
782+ self . interfaceCache = interfaces
783+ return interfaces
784+ } ( )
715785 }
716786}
717787
0 commit comments