Class: Lennarb::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/lennarb/base.rb

Overview

Base class for mounting applications with middleware support. This class serves as a proxy for mounting Lennarb::App instances, providing a lightweight router to dispatch requests to the appropriate app.

Examples:

Creating a mounting application

class Application < Lennarb::Base
  # Define base-level middleware
  middleware do
    use Rack::Session::Cookie, secret: "your_secret"
    use Rack::Protection
  end

  # Mount other applications
  mount(Blog, at: "/blog")
  mount(Admin, at: "/admin")
end

# Start the server
run Application.new

Since:

  • 1.4.0

Constant Summary collapse

AlreadyInitializedError =

This error is raised whenever the app is initialized more than once.

Since:

  • 1.0.0

Class.new(StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize {|self| ... } ⇒ Base

Initialize a new Base instance.

Yields:

  • (self)

    Block to configure the application

Since:

  • 1.0.0



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/lennarb/base.rb', line 127

def initialize(&block)
  @initialized = false
  @mounted_apps = {}
  @middleware = nil
  self.root = Pathname.pwd
  @env = Environment.new(compute_env)

  # Initialize mounted applications from class definition
  self.class.mounted_apps.each do |path, app_class|
    @mounted_apps[path] = app_class
  end

  instance_eval(&block) if block_given?
end

Instance Attribute Details

#envLennarb::Environment

The current environment.

Returns:

Since:

  • 1.0.0



111
112
113
# File 'lib/lennarb/base.rb', line 111

def env
  @env
end

#mounted_appsHash (readonly)

Get the mounted applications.

Returns:

  • (Hash)

    The mounted applications by path

Since:

  • 1.4.0



121
122
123
# File 'lib/lennarb/base.rb', line 121

def mounted_apps
  @mounted_apps
end

#rootPathname

The root directory of the application.

Returns:

  • (Pathname)

    The root directory

Since:

  • 1.0.0



116
117
118
# File 'lib/lennarb/base.rb', line 116

def root
  @root
end

Class Method Details

.config(*envs) {|config| ... } ⇒ Lennarb::Config

Define the app’s configuration at class level

Examples:

Configure for all environments

config do
  set :title, "My Application"
end

Configure for specific environments

config :development, :test do
  set :debug, true
end

Parameters:

  • envs (Array<Symbol>)

    Environments to apply the configuration to

Yields:

  • (config)

    Block to configure the application

Returns:

Since:

  • 1.4.0



70
71
72
73
74
# File 'lib/lennarb/base.rb', line 70

def config(*envs, &block)
  @config ||= Config.new
  @config.instance_eval(&block) if block_given?
  @config
end

.middleware {|middleware| ... } ⇒ Lennarb::MiddlewareStack

Define the app’s middleware stack at class level. This allows defining middleware that will be applied before routing to any mounted applications.

Examples:

middleware do
  use Rack::Session::Cookie, secret: "your_secret"
  use Rack::Protection
end

Yields:

Returns:

Since:

  • 1.4.0



49
50
51
52
53
# File 'lib/lennarb/base.rb', line 49

def middleware(&block)
  @middleware ||= MiddlewareStack.new
  @middleware.instance_eval(&block) if block_given?
  @middleware
end

.mount(component, at: nil) ⇒ void

This method returns an undefined value.

Mount a component at the given path.

Examples:

mount(Blog, at: "/blog")
mount(Admin, at: "/admin")

Parameters:

  • component (Class)

    The component to mount (must be a Lennarb::App subclass)

  • options (Hash)

    The mounting options

Raises:

  • (ArgumentError)

    If the component is not a Lennarb::App subclass

Since:

  • 1.4.0



87
88
89
90
91
92
93
94
# File 'lib/lennarb/base.rb', line 87

def mount(component, at: nil)
  if component.is_a?(Class) && component < Lennarb::App
    path = normalize_mount_path(at || "/")
    mounted_apps[path] = component
  else
    raise ArgumentError, "Component must be a Lennarb::App subclass"
  end
end

.mounted_appsHash

Store for mounted applications at class level

Returns:

  • (Hash)

    mounted applications by path

Since:

  • 1.4.0



32
33
34
# File 'lib/lennarb/base.rb', line 32

def mounted_apps
  @mounted_apps ||= {}
end

Instance Method Details

#app#call

The Rack app with all middlewares and mounted applications. This builds a middleware stack around the URL map of mounted applications.

Returns:

  • (#call)

    The Rack application

Since:

  • 1.0.0



216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/lennarb/base.rb', line 216

def app
  @app ||= begin
    url_map = build_url_map

    stack = middleware.to_a

    Rack::Builder.app do
      stack.each { |middleware, args, block| use(middleware, *args, &block) }
      run url_map
    end
  end
end

#call(env) ⇒ Array(Integer, Hash, #each)

Call the app - main Rack entry point. This method is called by Rack when a request is received.

Parameters:

  • env (Hash)

    The Rack environment

Returns:

  • (Array(Integer, Hash, #each))

    The Rack response

Since:

  • 1.0.0



235
236
237
238
239
240
241
# File 'lib/lennarb/base.rb', line 235

def call(env)
  # Store reference to the current app in the env
  env[RACK_LENNA_APP] = self

  # Call the app with middlewares
  app.call(env)
end

#config(*envs) {|config| ... } ⇒ Lennarb::Config

Define the app’s configuration.

Parameters:

  • envs (Array<Symbol>)

    Environments to apply the configuration to

Yields:

  • (config)

    Block to configure the application

Returns:

Since:

  • 1.4.0



166
167
168
169
170
171
172
173
174
175
# File 'lib/lennarb/base.rb', line 166

def config(*envs, &block)
  @config ||= Config.new

  write = block_given? &&
    (envs.map(&:to_sym).include?(env.to_sym) || envs.empty?)

  @config.instance_eval(&block) if write

  @config
end

#freeze!void

This method returns an undefined value.

Freeze the app.

Since:

  • 1.0.0



207
208
209
# File 'lib/lennarb/base.rb', line 207

def freeze!
  app.freeze
end

#initialize!self

Initialize the app.

Returns:

  • (self)

    The initialized app

Raises:

Since:

  • 1.4.0



188
189
190
191
192
# File 'lib/lennarb/base.rb', line 188

def initialize!
  raise AlreadyInitializedError if initialized?
  @initialized = true
  self
end

#initialized?Boolean

Check if the app is initialized.

Returns:

  • (Boolean)

    true if initialized, false otherwise

Since:

  • 1.4.0



180
181
182
# File 'lib/lennarb/base.rb', line 180

def initialized?
  @initialized
end

#middleware {|middleware| ... } ⇒ Lennarb::MiddlewareStack

Define the app’s middleware stack. Middleware defined here will be applied to all requests before they are routed to mounted applications.

Examples:

middleware do
  use Rack::Session::Cookie, secret: "your_secret"
  use Rack::Protection
end

Yields:

Returns:

Since:

  • 1.4.0



155
156
157
158
159
# File 'lib/lennarb/base.rb', line 155

def middleware(&block)
  @middleware ||= MiddlewareStack.new
  @middleware.instance_eval(&block) if block_given?
  @middleware
end

#mount(component, at: nil) ⇒ void

This method returns an undefined value.

Mount a component at the given path (instance method)

Examples:

mount(Blog, at: "/blog")

Parameters:

  • component (Class)

    The component to mount (must be a Lennarb::App subclass)

  • options (Hash)

    The mounting options

Raises:

  • (ArgumentError)

    If the component is not a Lennarb::App subclass

Since:

  • 1.4.0



253
254
255
256
257
258
259
260
# File 'lib/lennarb/base.rb', line 253

def mount(component, at: nil)
  if component.is_a?(Class) && component < Lennarb::App
    path = normalize_mount_path(at || "/")
    @mounted_apps[path] = component
  else
    raise ArgumentError, "Component must be a Lennarb::App subclass"
  end
end