Class: Desiru::GraphQL::SchemaGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/desiru/graphql/schema_generator.rb

Overview

Generates GraphQL schemas from Desiru signatures

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSchemaGenerator

Returns a new instance of SchemaGenerator.



14
15
16
17
18
19
20
# File 'lib/desiru/graphql/schema_generator.rb', line 14

def initialize
  @signatures = {}
  @modules = {}
  @type_cache = {} # Instance cache for schema-specific types
  @schema_class = nil
  @data_loader = DataLoader.new
end

Instance Attribute Details

#data_loaderObject (readonly)

Returns the value of attribute data_loader.



12
13
14
# File 'lib/desiru/graphql/schema_generator.rb', line 12

def data_loader
  @data_loader
end

#modulesObject (readonly)

Returns the value of attribute modules.



12
13
14
# File 'lib/desiru/graphql/schema_generator.rb', line 12

def modules
  @modules
end

#signaturesObject (readonly)

Returns the value of attribute signatures.



12
13
14
# File 'lib/desiru/graphql/schema_generator.rb', line 12

def signatures
  @signatures
end

Class Method Details

.clear_type_cache!Object

Clear the global type cache (useful for testing or reloading)



23
24
25
# File 'lib/desiru/graphql/schema_generator.rb', line 23

def self.clear_type_cache!
  TypeBuilder.clear_type_cache!
end

Instance Method Details

#add_query_field(query_class, field_name, field_def) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/desiru/graphql/schema_generator.rb', line 65

def add_query_field(query_class, field_name, field_def)
  # Add field directly without resolver class
  query_class.field field_name, field_def[:type],
                    null: false,
                    description: field_def[:description] do
    # Add arguments
    field_def[:arguments].each do |arg_name, arg_def|
      argument arg_name, arg_def[:type], required: arg_def[:required]
    end
  end

  # Define the resolver method for this field
  query_class.define_method field_name do |**args|
    if field_def[:module_instance].respond_to?(:batch_forward)
      # Get the dataloader for this request
      dataloader = context.dataloader
      # Load through the dataloader
      dataloader.with(
        Desiru::GraphQL::ModuleLoader,
        field_name,
        field_def[:modules]
      ).load(args)
    else
      # Direct execution
      field_def[:resolver].call(args, context)
    end
  end
end

#generate_schemaObject

Generate a GraphQL schema from registered signatures



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/desiru/graphql/schema_generator.rb', line 45

def generate_schema
  # Always rebuild if signatures have changed
  return @schema_class if @schema_class && @last_signature_count == @signatures.size

  @last_signature_count = @signatures.size
  query_class = build_query_type

  @schema_class = Class.new(::GraphQL::Schema) do
    query(query_class) if query_class

    # Enable GraphQL's built-in dataloader
    use ::GraphQL::Dataloader

    # Enable lazy execution for batch loading
    lazy_resolve(::GraphQL::Execution::Lazy, :value)
  end

  @schema_class
end

#register_module(name, module_instance) ⇒ Object

Register a module instance to handle a specific operation



33
34
35
36
37
# File 'lib/desiru/graphql/schema_generator.rb', line 33

def register_module(name, module_instance)
  @modules[name] = module_instance
  # Auto-register signature if module has one
  @signatures[name] ||= module_instance.signature if module_instance.respond_to?(:signature)
end

#register_modules(modules_hash) ⇒ Object

Register multiple modules at once



40
41
42
# File 'lib/desiru/graphql/schema_generator.rb', line 40

def register_modules(modules_hash)
  modules_hash.each { |name, mod| register_module(name, mod) }
end

#register_signature(name, signature) ⇒ Object

Register a signature with a name for GraphQL query/mutation



28
29
30
# File 'lib/desiru/graphql/schema_generator.rb', line 28

def register_signature(name, signature)
  @signatures[name] = signature
end